SYSTEM Cited by 1 source
ruby-saml¶
ruby-saml (github.com/SAML-Toolkits/ruby-saml)
is an open-source Ruby library implementing the service-provider (SP)
side of SAML SSO — response parsing, signature
verification, assertion validation. It is the dominant SAML-SP
implementation in the Ruby ecosystem and is consumed directly or via
omniauth-saml by a long
tail of Rails applications and notably by GitLab.
Architecture relevant to security¶
ruby-saml's xml_security.rb verifies a SAML response by combining
two XML parsers on the same input document:
- REXML — pure-Ruby XML parser (Ruby stdlib). Used
for locating the
<ds:Signature>element, extracting the<ds:SignatureValue>, locating<ds:SignedInfo>, extracting the<ds:Reference>, and extracting the<ds:DigestValue>. - Nokogiri — wrapper over libxml2 / libgumbo /
Xerces (via JRuby). Added because REXML lacks
canonicalisation support. Used to
canonicalise
<ds:SignedInfo>and to look up the referenced<Assertion>byIDattribute and canonicalise it for digest hashing.
The verification path has two asymmetric chains:
<ds:SignatureValue>(REXML) is verified against canonicalised<ds:SignedInfo>(Nokogiri).<ds:DigestValue>(REXML) is compared to the hash of canonicalised<Assertion>looked up by ID (Nokogiri).
Neither chain pins its two endpoints to the same byte range. If
REXML and Nokogiri disagree about which <ds:Signature> element an
XPath query returns, the signature and the digest can each verify in
isolation against pieces of different signature elements in the
same document — an authentication bypass.
CVE-2025-25291 + CVE-2025-25292 (2025-03-12)¶
Two distinct parser-differential exploits, independently found by
ahacker1 (XML-roundtrip technique, Mattermost 2021 lineage) and by
the GitHub Security Lab (coverage-guided fuzzing with Trail of Bits'
ruzzy).
Both yielded authentication bypass against any SP using ruby-saml
≤ 1.17.0. Attacker precondition: possession of any single valid
signature produced by the target organisation's IdP signing key —
obtainable from any signed assertion or, in some deployments, from
publicly-published signed IdP metadata.
Fixed in ruby-saml 1.18.0. The fix is gadget-specific — it re-uses
the already-extracted <SignedInfo> bytes as the source for the
digest comparison rather than re-querying the document — but does
not remove the second parser, since doing so would break
backwards-compatible API callers. Structural removal of one parser
PR #736 is
planned for a future major release.
Historical context¶
- 1.17.0 and earlier — vulnerable to CVE-2025-25291 + CVE-2025-25292.
- October 2024 — prior authentication bypass CVE-2024-45409
reported by
ahacker1, a different multi-signature SAML attack; ruby-saml added a guard requiring exactly one element with a givenID. This guard is still in place in 1.17.0 — the 2025 parser differentials route around it by placing the second signature in a<StatusDetail>element the ID-uniqueness check doesn't reach. - 1.18.0 (2025-03-12) — parser-differential fix for both 2025 CVEs.
- GitHub used ruby-saml until 2014, then moved to an in-house SAML implementation; the 2024-25 disclosure cycle began when GitHub was evaluating re-adoption of ruby-saml and opened a private bug-bounty engagement.
Downstream consumers to audit¶
- omniauth-saml — the OmniAuth strategy wrapper around ruby-saml; applications depending on a fixed ruby-saml version transitively must use an omniauth-saml release that references it.
- GitLab — confirmed exploitable instance, notified pre-disclosure; GitLab on-prem + SaaS both needed patching.
- Long tail of Rails applications using ruby-saml directly or via omniauth-saml.
Seen in¶
- sources/2025-03-15-github-sign-in-as-anyone-bypassing-saml-sso-authentication-with-parser-differentials
— canonical disclosure. CVE-2025-25291 + CVE-2025-25292; two
independent parser-differential exploits; 1.18.0 fix;
parser differential between
REXML and Nokogiri in
xml_security.rb'svalidate_signaturemethod; detection ~impossible ("we are not aware of any reliable indicators of compromise"); structural fix is patterns/single-parser-for-security-boundaries.
Related¶
- systems/rexml — ruby-saml's primary XML parser.
- systems/nokogiri — ruby-saml's canonicalisation parser; source of the second parser in the differential.
- systems/saml-protocol — the spec ruby-saml implements.
- systems/gitlab — the most prominent downstream consumer.
- concepts/parser-differential — the vulnerability class.
- concepts/xml-signature-wrapping — the attack family.
- concepts/saml-authentication-bypass — the outcome category.
- patterns/single-parser-for-security-boundaries — the structural fix.