Write-up: Password reset poisoning via middleware @ PortSwigger Academy

This write-up for the lab Password reset poisoning via middleware is part of my walkthrough series for PortSwigger’s Web Security Academy.

Learning path: Server-side topics → Authentication

Lab description


Analyze password reset process

As usual, the first step is to analyze the functionality of the lab, in this case, the password reset feature. Clicking on the “Forgot password?”-link and entering the username wiener, we receive a password reset email on our email account:

Password reset link

Clicking on the link allows setting a new password as one would expect. The request triggering this looks unremarkable, as does the one for actually setting the new password.

On the exploit server, I can create a web page, see the access logs of the exploit server and read the emails of wiener.

I can’t fake the second request directly as it requires the temp-forgot-password-token, which the server generates as a response to the first request. The token is dynamic and changes on every request regardless of whether the previous one was used or not.

But it is contained in the URL, so if the request can be manipulated to point to the exploit server, it will be written to the server log.

Manipulate the request

The request contains multiple headers referring to the host. If I can manage to include the exploit server, we might be able to obtain useful information in the access logs.

Request for resetting the password

As I have an own account and access to its emails, I can try this out. Attempting to manipulate the Origin and Referer values did not change the URL within the 'reset password' email.

Checking for possible headers on mozilla.org, one stands out quickly: X-Forwarded-Host.

It is used to identify the original host header sent by the client in scenarios where reverse proxies are in place that might replace the other headers. So I start to play reverse proxy.

I get the original request for the password reset, send it to Burp Repeater and add an X-Forwarded-Host header pointing to the exploit server.

New HTTP header added to the request

Sure enough, the email now contains a link to my exploit server, clicking it shows our token in the access log:

Manipulated link in the password reset email
The reset token is leaked in my exploit server

The malicious request

Now it becomes easy, I just change the username to carlos and send the request again:

Malicious request

And sure enough, true to his words carlos clicks on any link he receives:

Changing the password

The remaining step is trivial, I send the password change request of wiener to Repeater and change the token to the one obtained from carlos. I can now access his reset password page and set the password to a known value:

Changing the password for carlos

Logging in with the now known credentials results in:



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Frank Leitner

Tech nerd, doing security stuff for fun and some as a job | CISSP, OSCP. Read all stories on medium and support me: https://medium.com/@frank.leitner/membership