Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2025-48995

CVE-2025-48995: SignXML HMAC Timing Attack Vulnerability

CVE-2025-48995 is a timing attack flaw in SignXML that leaks HMAC information during signature verification. Attackers can exploit this to reconstruct valid HMACs. This article covers technical details, affected versions, and fixes.

Published:

CVE-2025-48995 Overview

CVE-2025-48995 is a timing side-channel vulnerability in SignXML, a Python implementation of the W3C XML Signature standard. The flaw affects versions prior to 4.0.4 when signature verification is configured with X509 certificate validation disabled and an HMAC shared secret. The signxml.XMLVerifier.verify(require_x509=False, hmac_key=...) code path uses a non-constant-time equality comparison to validate the HMAC. Attackers who can measure verification time can incrementally recover the correct HMAC value and forge signatures for arbitrary data. The weakness is classified as [CWE-208] Observable Timing Discrepancy.

Critical Impact

An attacker able to observe verification timing can reconstruct a valid HMAC for arbitrary XML payloads, bypassing signature verification and enabling forgery of signed messages.

Affected Products

  • SignXML Python library versions prior to 4.0.4
  • Applications invoking XMLVerifier.verify() with require_x509=False and an hmac_key
  • Downstream services relying on SignXML HMAC-based XML signature validation

Discovery Timeline

  • 2025-06-02 - CVE-2025-48995 published to NVD
  • 2026-06-17 - Last updated in NVD database

Technical Details for CVE-2025-48995

Vulnerability Analysis

SignXML validates HMAC signatures by comparing the raw signature bytes against a freshly computed HMAC digest. In vulnerable releases the comparison uses Python's == operator, which short-circuits on the first differing byte. Response time therefore scales with the number of matching leading bytes, forming a classic timing oracle.

An attacker who can submit signed XML documents and measure the verifier's response latency can determine the correct HMAC one byte at a time. Recovering the full digest allows the attacker to sign any content and pass verification. The impact is limited to deployments that explicitly opt out of X509 validation and use HMAC shared secrets, but for those deployments the integrity guarantee of the XML signature is defeated.

Root Cause

The root cause is the use of a non-constant-time byte comparison in the HMAC verification branch of signxml/verifier.py. Secure HMAC verification requires a constant-time comparison such as hmac.compare_digest or the HMAC.verify method exposed by the cryptography library.

Attack Vector

Exploitation requires network access to a verification endpoint and the ability to observe timing variance across many probe requests. No authentication or user interaction is needed. The attacker submits signed XML payloads with candidate HMAC values and measures response latency to iteratively converge on the correct digest.

python
# Security patch in signxml/verifier.py
            signer = HMAC(key=ensure_bytes(self.hmac_key), algorithm=digest_algorithm_implementations[signature_alg]())
            signer.update(signed_info_c14n)
-            if raw_signature == signer.finalize():
+            try:
+                signer.verify(raw_signature)
                verified_signed_info_c14n = signed_info_c14n
-            else:
+            except cryptography.exceptions.InvalidSignature:
                raise InvalidSignature("Signature mismatch (HMAC)")
        else:
            if key_value is None and der_encoded_key_value is None:
# Source: https://github.com/XML-Security/signxml/commit/1b501faaacf34cf978a52dbc6915ec11e27611cd

The patch replaces the vulnerable == comparison with signer.verify(raw_signature), which performs a constant-time check and raises InvalidSignature on mismatch.

Detection Methods for CVE-2025-48995

Indicators of Compromise

  • High volumes of XML signature verification requests originating from a small set of source addresses within short time windows.
  • Repeated verification failures against the same endpoint with slowly mutating signature values, consistent with byte-by-byte probing.
  • Successful verification of XML payloads that were not issued by any authorized signing service.

Detection Strategies

  • Inventory Python dependencies and flag any SignXML installation earlier than 4.0.4, particularly where require_x509=False and hmac_key are set.
  • Perform static analysis of application code for calls to XMLVerifier.verify that disable X509 validation and pass an HMAC key.
  • Add application-level metrics on verification latency and failure counts per client to surface enumeration behavior.

Monitoring Recommendations

  • Alert on sustained bursts of InvalidSignature exceptions from XML verification code paths.
  • Correlate WAF or API gateway logs for repeated POSTs of signed XML to the same endpoint from a single source.
  • Log and review the versions of security-critical libraries reported by CI and runtime software composition analysis.

How to Mitigate CVE-2025-48995

Immediate Actions Required

  • Upgrade SignXML to version 4.0.4 or later in all Python environments.
  • Audit all invocations of XMLVerifier.verify and confirm whether HMAC verification is in use.
  • Rotate any HMAC shared secrets that may have been exposed to untrusted verification traffic.

Patch Information

The fix is delivered in SignXML 4.0.4. The upstream commit replaces the non-constant-time comparison with HMAC.verify from the cryptography library. Reference the GitHub Security Advisory GHSA-gmhf-gg8w-jw42 and the upstream patch commit for release details.

Workarounds

  • Where feasible, require X509 certificate validation instead of HMAC by removing require_x509=False from verifier calls.
  • Rate-limit and add jitter to verification endpoints to reduce the signal-to-noise ratio of timing measurements.
  • Restrict access to XML signature verification services to authenticated internal callers until patching is complete.
bash
# Upgrade SignXML to a fixed release
pip install --upgrade 'signxml>=4.0.4'

# Verify the installed version
python -c "import signxml; print(signxml.__version__)"

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.