CVE-2025-29774: XML Signature Verification Bypass in xml-crypto
Executive Summary
CVE-2025-29774 is a critical vulnerability in the xml-crypto
library, an XML digital signature and encryption library for Node.js. This vulnerability, present in versions prior to 6.0.1, 3.2.1, and 2.1.6, allows an attacker to bypass signature verification mechanisms in systems that rely on xml-crypto
for validating signed XML documents. Exploiting this vulnerability could enable attackers to modify signed XML messages while maintaining valid signature verification, potentially leading to privilege escalation or user impersonation. Users are strongly advised to upgrade to the patched versions immediately.
- CVSS Score: 9.3 (Critical)
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: None
- User Interaction: None
- Impact: High Integrity and Confidentiality compromise
Technical Details
Affected Systems and Versions
The vulnerability affects the following versions of xml-crypto
:
- Versions prior to 6.0.1 (latest major release)
- Versions prior to 3.2.1 (legacy v3.x branch)
- Versions prior to 2.1.6 (legacy v2.x branch)
Vulnerable Component
The issue lies in the XML signature verification process within the SignedXml
class of the xml-crypto
library. Specifically, the vulnerability allows attackers to manipulate the SignedInfo
node in XML documents, bypassing signature validation.
Vulnerability Description
The vulnerability is rooted in the improper handling of the SignedInfo
element during the canonicalization and verification process. An attacker can craft malicious XML documents with multiple or wrapped SignedInfo
nodes, leading the library to validate an altered or malicious signature while ignoring the original signed content. This enables attackers to:
- Inject or modify critical attributes in signed XML documents.
- Escalate privileges by impersonating other users or bypassing access controls.
Root Cause Analysis
The root cause of the vulnerability is the library's failure to enforce strict validation of the SignedInfo
node during the signature verification process. Specifically:
- The library does not ensure that only one
SignedInfo
node is present in the XML document. - It fails to validate the canonicalized version of the
SignedInfo
node against the original signed content.
Code Analysis
The core of the issue lies in the SignedXml
class, particularly in the loadSignature
and checkSignature
methods. Below is a snippet of the vulnerable code:
// Vulnerable code in src/signed-xml.ts
const signedInfoCanon = this.getCanonSignedInfoXml(doc);
if (!signedInfoCanon) {
throw new Error("Canonical signed info cannot be empty");
}
signer.verifySignature(signedInfoCanon, key, this.signatureValue);
The library assumes that the SignedInfo
node is canonicalized correctly and does not validate the presence of multiple or wrapped SignedInfo
nodes.
Exploit Scenario
An attacker could craft an XML document with multiple SignedInfo
nodes, as shown below:
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#valid">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>VALID_DIGEST</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignedInfo>
<ds:Reference URI="#malicious">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>MALICIOUS_DIGEST</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
</ds:Signature>
The library incorrectly validates the malicious SignedInfo
node, allowing the attacker to bypass signature verification.
Patch Analysis
The patch for this vulnerability introduces stricter validation for the SignedInfo
node. Below is a detailed analysis of the patch:
Key Changes in src/signed-xml.ts
+ // Ensure only one SignedInfo node is present
const signedInfoNodes = utils.findChildren(this.signatureNode, "SignedInfo");
if (!utils.isArrayHasLength(signedInfoNodes)) {
throw new Error("no signed info node found");
}
if (signedInfoNodes.length > 1) {
throw new Error("could not load signature that contains multiple SignedInfo nodes");
}
- Addition: The patch ensures that the
SignedInfo
node is validated for uniqueness. If multiple nodes are found, the library throws an error.
+ // Validate canonicalization algorithm
let canonicalizationAlgorithmForSignedInfo = this.canonicalizationAlgorithm;
if (!canonicalizationAlgorithmForSignedInfo || canonicalizationAlgorithmForSignedInfo ===
"http://www.w3.org/TR/2001/REC-xml-c14n-20010315") {
canonicalizationAlgorithmForSignedInfo = "http://www.w3.org/2001/10/xml-exc-c14n#";
}
- Addition: The patch enforces the use of exclusive canonicalization (
xml-exc-c14n
) to prevent namespace injection attacks.
Test Cases Added
The patch also introduces new test cases to validate the fixes. For example:
it("throws an error for a document with multiple SignedInfo nodes", function () {
const xml = fs.readFileSync("./test/static/saml_multiple_signed_info_nodes.xml", "utf-8");
const sig = new SignedXml();
expect(() => sig.loadSignature(xml)).to.throw("could not load signature that contains multiple SignedInfo nodes");
});
Exploitation Techniques
Proof of Concept (PoC)
A crafted XML document with multiple SignedInfo
nodes can be used to exploit the vulnerability. Below is a simplified PoC:
- Create a malicious XML document with two
SignedInfo
nodes. - Use the
xml-crypto
library to validate the document. - Observe that the library incorrectly validates the malicious
SignedInfo
node.
const fs = require('fs');
const SignedXml = require('xml-crypto').SignedXml;
const xml = fs.readFileSync('./malicious.xml', 'utf-8');
const sig = new SignedXml();
sig.loadSignature(xml);
if (sig.checkSignature(xml)) {
console.log("Signature is valid (but should not be!)");
}
Real-World Impact
- Privilege Escalation: An attacker with a valid account can modify their privileges by altering signed attributes.
- Impersonation: Attackers can impersonate other users by modifying identity attributes in signed XML documents.
Mitigation Strategies
-
Upgrade: Update to the latest patched versions:
- v6.0.1 for the latest branch
- v3.2.1 for the legacy v3.x branch
- v2.1.6 for the legacy v2.x branch
-
Validate Input: Ensure that XML documents are validated against a strict schema before processing.
-
Use Exclusive Canonicalization: Enforce the use of
xml-exc-c14n
for all XML signature operations. -
Monitor Logs: Implement logging and monitoring to detect unusual XML signature verification failures.
-
Apply Defense-in-Depth: Use additional layers of authentication and authorization to mitigate the impact of signature bypass.
Timeline of Discovery and Disclosure
Date | Event |
---|---|
2025-02-15 | Vulnerability discovered |
2025-02-20 | Reported to xml-crypto maintainers |
2025-03-10 | Patch released |
2025-03-14 | CVE-2025-29774 publicly disclosed |
References
- Security Advisory for CVE-2025-29774
- GitHub Commit Fix
- NVD Entry for CVE-2025-29774
- XML Signature Standards
By addressing this vulnerability promptly, organizations can mitigate the risk of critical security breaches and maintain the integrity of their XML-based systems.