-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Description
π Security Issue: Host Header Injection β Password Reset Link Manipulation β Account Takeover
Severity: High
Vulnerability Type: Host Header Injection, Password Reset Link Manipulation, Account Takeover
Affected Component(s): Password reset email generation logic (e.g., functions using req.headers.host), authentication flows.
Attack Vector: Remote / unauthenticated
π§ Description
The application constructs password reset (and possibly other authentication-related) links using the Host header from incoming HTTP requests without proper validation.
An attacker can supply a malicious Host header when triggering a password reset for a victim. The generated password reset email then contains a link to the attacker's domain.
If the victim clicks this link, the attacker can intercept the reset token and take over the account.
π Vulnerable Code Example
const host = req.headers.host;
const protocol = req.headers['x-forwarded-proto'] || (host.includes('localhost') ? 'http' : 'https');
const resetLink = `${protocol}://${host}/reset-password?token=${token}`;The host value is embedded into password reset URLs without any validation
π§ͺ Steps to Reproduce
-
Go to the Forgot Password page for a victim account (e.g. [email protected]).
-
Intercept the HTTP request (e.g. using Burp Suite, curl, or a proxy).
-
Modify the Host header to an attacker-controlled domain:
Host: attacker.com -
Submit the password reset request.
-
The victim receives a password reset email with a malicious link:
https://attacker.com/reset-password?token=<victim-token>
-
If the victim clicks the link, their browser connects to attacker.com, leaking the token.
-
The attacker uses this token on the legitimate site to reset the password and take over the account.
β Result: Full account takeover of the victim.
π‘ Impact
-
Account Takeover of any user whose password reset email can be triggered.
-
High severity as the vulnerability affects authentication flows.
-
Can also be used for phishing, session fixation, or open redirect attacks.
π§° Suggested Remediation
-
Do not use req.headers.host or any client-supplied header for security-sensitive URLs.
-
Use a hardcoded, trusted base URL from environment variables or config:
const baseUrl = process.env.APP_BASE_URL; // e.g. https://app.example.com
const resetLink = `${baseUrl}/reset-password?token=${token}`;
-
Optionally, validate the Host header against a whitelist if dynamic host resolution is required.
-
Add automated tests to ensure password reset URLs always use the legitimate domain