SAML attacks
TL;DR: XML signature wrapping, comment injection, IdP confusion, replay across SPs.
What it is
SAML 2.0 is a federation protocol where an Identity Provider issues an XML <Response> containing a signed <Assertion> about a user, which the Service Provider consumes. The XML signature is positional — it covers specific elements identified by Reference URI. Bugs come from XML parsing/signing mismatches, weak comparison, and audience/recipient confusion.
Preconditions / where it applies
- SP consumes SAML responses (POST binding to
/SAML2/POST/SSOor similar) - Verification pipeline parses XML twice (once to extract signature target, once to read claims), with possible inconsistency
- IdP metadata configured with a public key the attacker can sign or forge against
Technique
- XML Signature Wrapping (XSW) — duplicate the signed
<Assertion>element. Signature verifier finds the signed copy (by id) and validates it; claims reader walks the document and reads the other, attacker-modified copy. Eight canonical XSW variants per Mainka et al.; tools: SAML Raider (Burp extension).1 2 3 4
<Response> <Assertion ID="A1"> <!-- attacker, NameID=admin --> ... </Assertion> <Assertion ID="A2"> <!-- original signed copy --> <Signature .../> </Assertion> </Response>
- Comment / null-byte injection in NameID —
<NameID>admin<!--comment-->@evil</NameID>. Some parsers concatenate text nodes ignoring comments, others stop at comment. Signature validates againstadmin<!--comment-->@eviltext, app readsadmin. Classic Duo / OneLogin 2018 bug. xmlns/ canonicalisation differences — exclusive-c14n vs inclusive; namespace context manipulation changes the signed bytes’ meaning to the consumer.xsi:typeconfusion — modify schema type so the parser interprets a node differently.Recipient/Destination/AudienceRestrictionnot validated — replay a victim’s signed assertion to a different SP. Or strip the AudienceRestriction entirely (some libs ignore missing fields).NotBefore/NotOnOrAfternot enforced — replay old assertions.- Unsigned response, signed assertion — attacker rewraps a signed assertion inside a fresh, unsigned
<Response>they construct; SP checks only assertion signature. - Untrusted IdP — SP loads IdP metadata from a URL; replace the cert via ssrf or DNS hijack and sign with attacker key.
- Algorithm downgrade — force
xmldsig#rsa-sha1orxmldsig#dsa-sha1even when stronger is supported; sometimesnoneaccepted. - Parser differential — REXML vs Nokogiri vs libxml — see parser-differential-saml-ruby for the 2024 Ruby case study.
Detection and defence
- Use a SAML library that validates signature before any XPath/DOM access, and re-validates that the signed element is the one being read.
- Strictly validate
Issuer,Destination,Recipient,AudienceRestriction,InResponseTo,NotBefore,NotOnOrAfter. - Disable SHA-1 and
none; require RSA-SHA256 minimum. - Pin IdP cert in SP config; never auto-fetch metadata over plain HTTP; verify metadata signature.
- Reject responses with multiple
<Assertion>elements. - Logs:
Issuernot in allowlist, signature alg downgrade, repeatedInResponseTo. - Related: parser-differential-saml-ruby, sso-attacks, oauth-flows, jwt, xxe.
References
- HackTricks — SAML attacks — XSW catalog
- Mainka et al. — On breaking SAML — XSW theory
- Duo — SAML response signing flaws — 2018 comment-injection class