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:

  1. Inject or modify critical attributes in signed XML documents.
  2. 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:

  1. The library does not ensure that only one SignedInfo node is present in the XML document.
  2. 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:

  1. Create a malicious XML document with two SignedInfo nodes.
  2. Use the xml-crypto library to validate the document.
  3. 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

  1. 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
  2. Validate Input: Ensure that XML documents are validated against a strict schema before processing.

  3. Use Exclusive Canonicalization: Enforce the use of xml-exc-c14n for all XML signature operations.

  4. Monitor Logs: Implement logging and monitoring to detect unusual XML signature verification failures.

  5. 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

By addressing this vulnerability promptly, organizations can mitigate the risk of critical security breaches and maintain the integrity of their XML-based systems.

Read more