Full Report
Security Assertion Markup Language (SAML) is an authentication standard built on XML. This article dives into some of the issues around SAML and XML parsers that lead to major security issues. The Service Provider-Initiated SAML flow is the most common way that users authenticate through SAML. When a user tries to access a protected resource, a redirect to the Identity provider is made for verification. The IdP receives the request, verifies its validity and issues a SAML response with a digitally assertion. The response is sent back via the user's browser to the service provider. The service provider then verifies the digital signature and extracts the user information required for authorization checks. XML Signature Wrapping Attacks (XSW) occur when the signature validation and assertion process are handled by different modules or even different XML parsers. This is a classic difference between the verification and use steps. In a previous blog post on Gitlab, another Portswigger researcher showed how it was possible to bypass authentication using differences between parsers. This is discussed as a way to start looking for other issues in the same Ruby SAML parser. The new issue is around Canonicalization. In SAML, the XML needs to be put into a canonical state in order to be signed. According to the specification, relative URIs cannot be used. When a parser comes across this limitation it will return an error instead of an empty string. Since most parsers continue on this means that the data being signed over is effectively null! If you had a signature for null, then you'd be able to abuse this issue as a golden ticket. How do we get the signature? Sometimes, the error message are signed. By causing an error prior to being signed, an empty string may be signed. SAML metadata can be another route for this as well. Overall, a good post on XML processing for SAML. I personally found the article a little hard to follow with what was novel/new and what was prior knowledge. The void-canonical issue was super interesting!
Analysis Summary
# Vulnerability: SAML Canonicalization Null-Signature Bypass
## CVE Details
- **CVE ID:** CVE-2024-45409 (Note: Based on context of Ruby SAML/GitLab research referenced)
- **CVSS Score:** 10.0 (Critical)
- **CWE:** CWE-347 (Improper Verification of Cryptographic Signature), CWE-444 (Inconsistent Interpretation of HTTP Requests)
## Affected Systems
- **Products:** Ruby SAML library, GitLab (via OmniAuth SAML)
- **Versions:**
- Ruby SAML versions < 1.17.0
- GitLab versions < 17.3.3, 17.2.7, 17.1.8, 17.0.8, and 16.11.10
- **Configurations:** Service Provider (SP)-Initiated SAML flows where the application relies on the Ruby SAML library for assertion verification.
## Vulnerability Description
The vulnerability stems from a flaw in how the XML parser handles **Canonicalization (C14N)** errors. In the SAML flow, XML must be converted into a standardized (canonical) state before a digital signature is verified.
According to SAML specifications, relative URIs are prohibited during this process. When the parser encounters an invalid configuration—such as a relative URI—it triggers an exception. However, instead of halting the process, the parser returns an error state that the wrapping logic treats as an empty string (null). Consequently, the signature validation is performed against a "null" value. If an attacker can obtain a valid signature for an empty/null string (often found in signed error messages or specific metadata responses), they can bypass the entire authentication mechanism and forge assertions.
## Exploitation
- **Status:** PoC documented; high risk of exploitation in the wild for unpatched instances.
- **Complexity:** Medium (Requires understanding of XML signature wrapping and canonicalization tricks).
- **Attack Vector:** Network (Remote).
## Impact
- **Confidentiality:** High (Full access to user accounts and data).
- **Integrity:** High (Ability to forge identity assertions and modify data).
- **Availability:** High (Potential for account takeover of administrative users).
## Remediation
### Patches
- **Ruby SAML:** Upgrade to version 1.17.0 or later.
- **GitLab:** Update to versions 17.3.3, 17.2.7, 17.1.8, 17.0.8, or 16.11.10.
### Workarounds
- Enforce strict XML schema validation prior to signature processing to reject documents containing relative URIs.
- Disable SAML authentication temporarily if patches cannot be applied immediately, reverting to alternative OIDC or local providers.
## Detection
- **Indicators of Compromise:** Unusual SAML assertions containing relative URIs in attributes or namespaces. Logs showing successful logins with mismatched attribute signatures.
- **Detection methods and tools:** Audit SAML response logs for "Void-canonical" patterns or unexpected error-handling behavior during the C14N phase.
## References
- **Vendor Advisory:** hxxps[://]about[.]gitlab[.]com/releases/2024/09/17/patch-release-gitlab-17-3-3-released/
- **Ruby SAML Advisory:** hxxps[://]github[.]com/SAML-Toolkits/ruby-saml/security/advisories/GHSA-jwvw-xrrj-c38h
- **Research Blog:** hxxps[://]portswigger[.]net/research/wide-ranging-impact-of-xml-canonicalization-issues