You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<script>location = new URLSearchParams(location.search).get('next')</script>
263
263
```
264
264
265
+
### Fragment smuggling + client-side traversal chain (Grafana-style bypass)
266
+
267
+
- **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`:
- Parsing sees `Path=/` and `Fragment=/..//\//attacker.com`, so regex + `path.Clean()` approve `/`, but the response emits `Location: /\//attacker.com`, acting as an open redirect.
270
+
- **Client-side gap (validate decoded/cleaned, return original)**: SPA helpers that fully decode a path (including double-encoded `?`), strip the query for validation, but thenreturn 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:
- 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.
0 commit comments