CVE-2026-113729
Moov signedxml: Unauthenticated denial of service in exclusive XML canonicalization
Moov signedxml is a pure Go library for processing signed XML documents. Prior to 1.4.1, ExclusiveCanonicalization in exclusivecanonicalization.go copies the complete accumulated namespace map at every nested element before reference digest or signature checks. Attacker-controlled XML containing deeply nested elements with many unused namespace declarations causes quadratic allocation growth with depth and linear growth with prefixes per level, allowing a comparatively small document to consume multiple gigabytes of memory and terminate the process. The condition is reachable through ValidateReferences without a valid signature, matching certificate, or prior authentication, and it does not bypass signature verification. This issue is fixed in version 1.4.1.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
7.5
Moov signedxml: Unauthenticated denial of service in exclusive XML canonicalization
Moov signedxml is a pure Go library for processing signed XML documents. Prior to 1.4.1, ExclusiveCanonicalization in exclusivecanonicalization.go copies the complete accumulated namespace map at every nested element before reference digest or signature checks. Attacker-controlled XML containing deeply nested elements with many unused namespace declarations causes quadratic allocation growth with depth and linear growth with prefixes per level, allowing a comparatively small document to consume multiple gigabytes of memory and terminate the process. The condition is reachable through ValidateReferences without a valid signature, matching certificate, or prior authentication, and it does not bypass signature verification. This issue is fixed in version 1.4.1.
- Record
CVE-2026-113729- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-400, CWE-407, CWE-770
- Updated
- 2026-11-02
EUVDEUVD-2026-105774
7.5
Moov signedxml is a pure Go library for processing signed XML documents. Prior to 1.4.1, ExclusiveCanonicalization in exclusivecanonicalization.go copies the complete accumulated namespace map at every nested element before reference digest or signature checks. Attacker-controlled XML containing deeply nested elements with many unused namespace declarations causes quadratic allocation growth with depth and linear growth with prefixes per level, allowing a comparatively small document to consume multiple gigabytes of memory and terminate the process. The condition is reachable through ValidateReferences without a valid signature, matching certificate, or prior authentication, and it does not bypass signature verification. This issue is fixed in version 1.4.1.
- Record
EUVD-2026-105774- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-5588-rp99-5fjh
7.5
Moov signedxml: Unauthenticated denial of service in exclusive XML canonicalization
Exclusive XML canonicalization (http://www.w3.org/2001/10/xml-exc-c14n#) in github.com/moov-io/signedxml copied the entire accumulated namespace map at every node during ValidateReferences(), before any reference digest or signature check.
For a chain of nested elements that each declare many unused namespace prefixes, that produced O(m × depth²) time and peak memory (m = prefixes per level). beevik/etree caps tree depth (~1024), but m is unbounded, so a small attacker-controlled document (on the order of 1 MB) could drive multi-gigabyte allocations and OOM the process. No valid signature, matching certificate, or authentication is required.
This is the library’s core path for SAML / WS-Federation service providers, which canonicalize attacker-supplied XML prior to authentication.
Affected
- Package:
github.com/moov-io/signedxml - Function:
ExclusiveCanonicalization(exclusivecanonicalization.go) - Verified: v1.4.0 and current default branch (commit
d79064a). Earlier v1.2.x–v1.3.x releases are likely affected.
Remediation
Do not copy the whole namespace map per node. Maintain a single scope and push/pop only the prefixes introduced at each element. Replace linear prefix-in-scope scans with set lookups. Impose a defensive cap on in-scope namespace declarations and return an error rather than allocating unbounded memory.
From @shuji-oh
Thanks for the fix — I re-ran my PoC against this branch and confirmed the memory blowup is gone.
Before (main)
-- Doubling depth each time (m=10 fixed): allocated grows ~4x each time ≈ O(depth^2) --
depth=250 m=10 payload= 0.07MB allocated= 45MB
depth=500 m=10 payload= 0.14MB allocated= 179MB
depth=1000 m=10 payload= 0.27MB allocated= 711MB
-- Increasing m (depth=1000 fixed): allocated scales roughly linearly with m --
depth=1000 m=5 payload= 0.16MB allocated= 377MB
depth=1000 m=100 payload= 2.57MB allocated= 6278MB
After (fix/exc-c14n-namespace-dos)
-- Doubling depth each time (m=10 fixed): allocated grows ~4x each time ≈ O(depth^2) --
depth=250 m=10 payload= 0.07MB allocated= 2MB
depth=500 m=10 payload= 0.14MB allocated= 4MB
depth=1000 m=10 payload= 0.27MB allocated= 7MB
-- Increasing m (depth=1000 fixed): allocated scales roughly linearly with m --
depth=1000 m=5 payload= 0.16MB allocated= 4MB
depth=1000 m=100 payload= 2.57MB allocated= 47MB
That's roughly a 100–130x reduction in peak allocation for the same payload sizes, and no OOM in any of my runs. This looks like it resolves the issue — thanks for the quick fix!
Credit
Reported by Shuji Ohira (@shuji-oh).
- Record
GHSA-5588-rp99-5fjh- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-400, CWE-407, CWE-770
- Updated
- 2026-11-02
NVD
7.5
Moov signedxml is a pure Go library for processing signed XML documents. Prior to 1.4.1, ExclusiveCanonicalization in exclusivecanonicalization.go copies the complete accumulated namespace map at every nested element before reference digest or signature checks. Attacker-controlled XML containing deeply nested elements with many unused namespace declarations causes quadratic allocation growth with depth and linear growth with prefixes per level, allowing a comparatively small document to consume multiple gigabytes of memory and terminate the process. The condition is reachable through ValidateReferences without a valid signature, matching certificate, or prior authentication, and it does not bypass signature verification. This issue is fixed in version 1.4.1.
- Record
CVE-2026-113729- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-400, CWE-407, CWE-770
- Updated
- 2026-11-02
OSV
7.5
Moov signedxml: Unauthenticated denial of service in exclusive XML canonicalization
Moov signedxml is a pure Go library for processing signed XML documents. Prior to 1.4.1, ExclusiveCanonicalization in exclusivecanonicalization.go copies the complete accumulated namespace map at every nested element before reference digest or signature checks. Attacker-controlled XML containing deeply nested elements with many unused namespace declarations causes quadratic allocation growth with depth and linear growth with prefixes per level, allowing a comparatively small document to consume multiple gigabytes of memory and terminate the process. The condition is reachable through ValidateReferences without a valid signature, matching certificate, or prior authentication, and it does not bypass signature verification. This issue is fixed in version 1.4.1.
- Record
CVE-2026-113729- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-400, CWE-407, CWE-770
- Updated
- 2026-11-02
OSVGHSA-5588-rp99-5fjh
7.5
Moov signedxml: Unauthenticated denial of service in exclusive XML canonicalization
Exclusive XML canonicalization (http://www.w3.org/2001/10/xml-exc-c14n#) in github.com/moov-io/signedxml copied the entire accumulated namespace map at every node during ValidateReferences(), before any reference digest or signature check.
For a chain of nested elements that each declare many unused namespace prefixes, that produced O(m × depth²) time and peak memory (m = prefixes per level). beevik/etree caps tree depth (~1024), but m is unbounded, so a small attacker-controlled document (on the order of 1 MB) could drive multi-gigabyte allocations and OOM the process. No valid signature, matching certificate, or authentication is required.
This is the library’s core path for SAML / WS-Federation service providers, which canonicalize attacker-supplied XML prior to authentication.
Affected
- Package:
github.com/moov-io/signedxml - Function:
ExclusiveCanonicalization(exclusivecanonicalization.go) - Verified: v1.4.0 and current default branch (commit
d79064a). Earlier v1.2.x–v1.3.x releases are likely affected.
Remediation
Do not copy the whole namespace map per node. Maintain a single scope and push/pop only the prefixes introduced at each element. Replace linear prefix-in-scope scans with set lookups. Impose a defensive cap on in-scope namespace declarations and return an error rather than allocating unbounded memory.
From @shuji-oh
Thanks for the fix — I re-ran my PoC against this branch and confirmed the memory blowup is gone.
Before (main)
-- Doubling depth each time (m=10 fixed): allocated grows ~4x each time ≈ O(depth^2) --
depth=250 m=10 payload= 0.07MB allocated= 45MB
depth=500 m=10 payload= 0.14MB allocated= 179MB
depth=1000 m=10 payload= 0.27MB allocated= 711MB
-- Increasing m (depth=1000 fixed): allocated scales roughly linearly with m --
depth=1000 m=5 payload= 0.16MB allocated= 377MB
depth=1000 m=100 payload= 2.57MB allocated= 6278MB
After (fix/exc-c14n-namespace-dos)
-- Doubling depth each time (m=10 fixed): allocated grows ~4x each time ≈ O(depth^2) --
depth=250 m=10 payload= 0.07MB allocated= 2MB
depth=500 m=10 payload= 0.14MB allocated= 4MB
depth=1000 m=10 payload= 0.27MB allocated= 7MB
-- Increasing m (depth=1000 fixed): allocated scales roughly linearly with m --
depth=1000 m=5 payload= 0.16MB allocated= 4MB
depth=1000 m=100 payload= 2.57MB allocated= 47MB
That's roughly a 100–130x reduction in peak allocation for the same payload sizes, and no OOM in any of my runs. This looks like it resolves the issue — thanks for the quick fix!
Credit
Reported by Shuji Ohira (@shuji-oh).
- Record
GHSA-5588-rp99-5fjh- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-400, CWE-407, CWE-770
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
github.com/moov-io/signedxmlGo |
through 1.4.0 | 1.4.1 |
github.com/moov-io/signedxmlGo |
before 1.4.1 | 1.4.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-113729 is a high vulnerability (CVSS 7.5) in Moov-io Signedxml, published October 20, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.46%, the 39th percentile. Fixed in github.com/moov-io/signedxml 1.4.1.
References
github.com/moov-io/signedxml/security/advisories/GHSA-5588-rp99-5fjh
github.com/moov-io/signedxml/commit/da2cd6126c4c53b7e59a367d287786e6f6a2d0d3
github.com/moov-io/signedxml/releases/tag/v1.4.1
nvd.nist.gov/vuln/detail/CVE-2026-113729
github.com/advisories/GHSA-5588-rp99-5fjh
github.com/CVEProject/cvelistV5/tree/main/cves/2026/113xxx/CVE-2026-113729.json
github.com/moov-io/signedxml