【翻译】[하루한줄] CVE-2025-29774, CVE-2025-29775 xml-crypto의 XML Signature Wrapping 취약점
URL
https://workos.com/blog/samlstorm
Target
-
xml-crypto 库 (版本 <= 6.0.0)
Explain
该漏洞利用 XML 数字签名验证逻辑中的缺陷,可绕过 SAML 响应或基于 XML 签名的认证机制。该漏洞源于 xml-crypto
库签名验证方式的结构性问题,分为 CVE-2025-29774 和 CVE-2025-29775 两个漏洞公开。
CVE-2025-29774 是利用 "SignedInfo 节点重复" 的漏洞。在正常的已签名 XML 文档中,<Signature>
节点内应仅存在一个 <SignedInfo>
节点。然而,xml-crypto
的漏洞版本在存在多个 <SignedInfo>
节点时,会对攻击者插入的伪造 <SignedInfo>
节点进行签名验证,而不是验证正常的节点。这使得攻击者可以保留一个有效的 SignedInfo,同时在另一个节点中包含权限提升或用户篡改等恶意操作,从而绕过签名验证。在实际攻击示例中,攻击者会在 <Signature>
块中插入两个 <SignedInfo>
,并在其中一个包含伪造的 Digest 值,以实现认证绕过。
CVE-2025-29775 是基于 DigestValue 操作的漏洞。该漏洞通过在 DigestValue 中插入 HTML 注释 (<!-- -->
) 的方式实现。正常的 DigestValue 应为 Base64 编码的纯数据,但 xml-crypto 的验证逻辑并未基于节点解析该值,而是基于字符串处理。因此,攻击者可以插入如下所示的注释和伪造值:
<DigestValue>
<!--TBlYWE0ZWM4ODI1NjliYzE3NmViN2E1OTlkOGDhhNmI=-->
c7RuVDYo83z2su5uk0Nla8DXcXvKYKgf7tZklJxL/LZ=
</DigestValue>
验证逻辑会忽略注释,仅验证实际的 DigestValue,因此会认为签名有效。然而,解析的应用程序会将注释和值结合起来处理,导致错误的数据。这使得攻击者能够巧妙地更改用户的身份信息或权限信息,同时绕过签名验证。
攻击者可以利用此漏洞进行认证绕过和权限提升攻击。这对所有基于 xml-crypto
实现 SAML SSO 的服务都有广泛影响,特别是即使包含重要身份信息或权限信息的 XML 消息被篡改,仍然能够通过签名验证,这是一个严重的问题。
该漏洞已在 xml-crypto
库的 6.0.1 版本中修复。所有 6.0.0 及以下版本均受影响。
-
SignedInfo 节点重复检测 (CVE-2025-29774 检测方法)
需要检查 SAML 响应或 XML 文档中
<Signature>
内是否存在两个或更多<SignedInfo>
节点。正常文档中必须只有一个。<Signature>
<SomeNode>
<SignedInfo>
<ReferenceURI="somefakereference">
<DigestValue>forgeddigestvalue</DigestValue>
</Reference>
</SignedInfo>
</SomeNode>
<SignedInfo>
<ReferenceURI="realsignedreference">
<DigestValue>realdigestvalue</DigestValue>
</Reference>
</SignedInfo>
</Signature>
检测用的 JavaScript 代码如下:
const signedInfoNodes = xpath.select(".//*[local-name(.)='SignedInfo']", signatureNode);
if (signedInfoNodes.length > 1) {
// Compromise detected
}
-
DigestValue 内注释检测 (CVE-2025-29775 检测方法)
在正常的 XML 签名中,
<DigestValue>
块内绝对不应存在<!-- -->
形式的注释。如果发现此类情况,应将其视为被篡改的消息。<DigestValue>
<!-- malicious comment -->
validDigestValue==
</DigestValue>
检测用的 JavaScript 代码如下:
const digestValues = xpath.select("//*[local-name()='DigestValue'][count(node()) > 1]", decryptedDocument);
if (digestValues.length > 0) {
// Compromise detected
}
参考文档 (Reference)
-
xml-crypto 安全公告 GHSA-x3m8-899r-f7c3 -
xml-crypto 安全公告 GHSA-9p8x-f768-wp2g
原文始发于微信公众号(securitainment):CVE-2025-29774/CVE-2025-29775: xml-crypto XML Signature Wrapping
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论