# CSRF (Cross Site Request Forgery) ## What is CSRF? **Cross-site request forger**y (also known as CSRF) is a web security vulnerability that allows an attacker to **induce users to perform actions that they do not intend to perform**. \ This is done by **making a logged in user** in the victim platform access an attacker controlled website and from there **execute** malicious JS code, send forms or retrieve "images" to the **victims account**. ### Requisites In order to be able to abuse a CSRF vulnerability you first need to **find a relevant action to abuse** (change password or email, make the victim follow you on a social network, give you more privileges...). The **session must rely only on cookies or HTTP Basic Authentication header**, any other header can't be used to handle the session. An finally, there **shouldn't be unpredictable parameters** on the request. Several **counter-measures** could be in place to avoid this vulnerability. ### **Common defenses** * [**SameSite cookies**](hacking-with-cookies/#samesite): If the session cookie is using this flag, you may not be able to send the cookie from arbitrary web sites. * [**Cross-origin resource sharing**](cors-bypass.md): Depending on which kind of HTTP request you need to perform to abuse the relevant action, you may take int account the **CORS policy of the victim site**. _Note that the CORS policy won't affect if you just want to send a GET request or a POST request from a form and you don't need to read the response._ * Ask for the **password** user to authorise the action. * Resolve a **captcha** * Read the **Referrer** or **Origin** headers. If a regex is used it could be bypassed form example with: * http://mal.net?orig=http://example.com (ends with the url) * http://example.com.mal.net (starts with the url) * **Modify** the **name** of the **parameters** of the Post or Get request * Use a **CSRF token** in each session. This token has to be send inside the request to confirm the action. This token could be protected with CORS. ### CSRF map ![](<../.gitbook/assets/image (112).png>) ## Defences Bypass ### From POST to GET Maybe the form you want to abuse is prepared to send a **POST request with a CSRF token but**, you should **check** if a **GET** is also **valid** and if when you send a GET request the **CSRF token is still being validated**. ### Lack of token Some applications correctly **validate the token when it is present but skip the validation if the token is omitted**.\ In this situation, the attacker can **remove the entire parameter** containing the token (not just its value) to bypass the validation and deliver a CSRF attack. ### CSRF token is not tied to the user session Some applications do **not validate that the token belongs to the same session** as the user who is making the request. Instead, the application **maintains a global pool of tokens** that it has issued and accepts any token that appears in this pool.\ In this situation, the attacker can log in to the application using their own account, **obtain a valid token**, and then **feed that token to the victim** user in their CSRF attack. ### 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**_ This could also works sending the **\_method parameter inside the a POST request** or using the **headers**: * _X-HTTP-Method_ * _X-HTTP-Method-Override_ * _X-Method-Override_ ### Custom header token bypass If the request is adding a **custom header** with a **token** to the request as **CSRF protection method**, then: * Test the request without the **Customized Token and also header.** * Test the request with exact **same length but different token**. ### CSRF token is verified by a cookie In a further variation on the preceding vulnerability, some applications **duplicate each token within a cookie and a request parameter**. Or the **set a csrf cookie** and the **checks in the backend if the csrf token sent is the one related with the cookie**. When the subsequent request is validated, the application simply verifies that the **token** submitted in the **request parameter matches** the value stored by the **cookie**.\ In this situation, the attacker can again perform a CSRF **attack if the web site contains any vulnerability what would allow him to set his CSRF cookie to the victim like a CRLF**. In this case you can set the cookie trying to load a fake image and then launch the CSRF attack like in this example: ```html
``` {% hint style="info" %} Note that if the **csrf token is related with the session cookie this attack won't work** because you will need to set the victim your session, and therefore you will be attacking yourself. {% endhint %} ### Content-Type change According to [**this**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple\_requests), in order to **avoid preflight** requests using **POST** method these are the allowed Content-Type values: * **`application/x-www-form-urlencoded`** * **`multipart/form-data`** * **`text/plain`** However, note that the **severs logic may vary** depending on the **Content-Type** used so you should try the values mentioned and others like **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._ ### application/json preflight request bypass As you already know, you cannot sent a POST request with the Content-Type **`application/json`** via HTML form, and if you try to do so via **`XMLHttpRequest`** a **preflight** request is sent first.\ However, you could try to send the JSON data using the content types **`text/plain` and `application/x-www-form-urlencoded` ** just to check if the backend is using the data independently of the Content-Type.\ You can send a form using `Content-Type: text/plain` setting **`enctype="text/plain"`** If the server is only accepting the content type "application/json", you can **send the content type "text/plain; application/json"** without triggering a preflight request. You could also try to **bypass** this restriction by using a **SWF flash file**. More more information [**read this post**](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937). ### Referrer / Origin check bypass #### Avoid Referrer header Some applications validate the Referer header when it is present in requests but **skip the validation if the header is omitted**. ```markup ``` #### Regexp bypasses {% content-ref url="ssrf-server-side-request-forgery/url-format-bypass.md" %} [url-format-bypass.md](ssrf-server-side-request-forgery/url-format-bypass.md) {% endcontent-ref %} To set the domain name of the server in the URL that the Referrer is going to send inside the parameters you can do: ```html ``` ## **Exploit Examples** ### **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/#xss-stealing-csrf-tokens) vulnerability or a [**Dangling Markup**](dangling-markup-html-scriptless-injection.md) vulnerability. ### **GET using HTML tags** ```markup