-
Notifications
You must be signed in to change notification settings - Fork 36
Description
Hello,My name is Nyein Chan Aung and I am a bug bounty hunter from Myanmar,I have identified a critical vulnerability that is affected to latest version of this product.Can we assign a CVE for this Vulnerability and resolve together?.
You can contact me here bugdotexe@wearehackerone.com
Description
Host header injection & insecure password-reset link (magic link uses untrusted req.headers.host + http) leading to account takeover
Vulnerability Type: Host header injection → password-reset link poisoning (magic link uses untrusted req.headers.host + http)
CVSS v4 Estimated Severity: 8.2 (High) — Estimated score; see Impact Analysis.
Date: 2025-09-19
1. Executive summary
- Vulnerable code:
mailer.sendFromTemplate({
template: 'forgotPassword',
user: user,
token: token,
host: req.headers.host,
protocol: req.protocol,
acceptLanguage: req.headers['accept-language']
}, callback);
}-
Issue: The application builds absolute password-reset (magic) links using the untrusted
req.headers.hostheader and forces thehttp://scheme. An attacker who can control theHostheader (or exploit a misconfigured proxy/load-balancer that forwards the header unchanged) can cause reset links to point to attacker-controlled domains or be delivered via insecure HTTP, enabling token theft, phishing, and account takeover. -
Immediate risk: High — exposure or interception of reset tokens can lead to account takeover and credential theft.
-
Suggested immediate action: Stop using
req.headers.hostto build absolute links. Use a configured canonical base URL that includeshttps://(e.g.,BASE_URL=https://app.example.com).
2. Affected components
-
Password-reset / magic-link generation logic.
-
Email templates that include the magic-link.
-
Any proxy, load balancer, or gateway that forwards
Hostheaders without validation. -
Any other code paths that use
req.headers.hostto generate links or redirects.
3. Discovery details
-
During code review the application was observed building the magic link directly from
req.headers.hostand string-concatenating withhttp://. -
req.headers.hostcan be controlled by an attacker who can send requests to the application (or to an intermediary that forwards headers unchanged). If an email containing the magic link is generated based on such a request, the email may contain an attacker-controlled domain. -
Because the link is absolute and uses plaintext HTTP, an attacker can:
-
Host a domain that receives token-bearing links and capture the token.
-
Phish users with a page that looks like the real reset page but forwards token and credentials to the attacker.
-
Intercept tokens on insecure networks (HTTP downgrade).
-
4. Proof-of-Concept (non-exploitative)
This PoC shows how an attacker-supplied
Hostheader could result in an email that includes an attacker domain. Do not use this to target real accounts without authorization.
# Attacker triggers password-reset email while supplying a fake Host header
curl -s -X POST "https://note-vault.app/reset-password/${resetToken}" \
-H "Host: attacker.example.net" \
-d "email=victim@example.com"
The password reset email will contain a link like:
http://attacker.example.net/reset-password/{token}
An attacker controlling attacker.example.net can collect the token or present a phishing UI that extracts credentials or the token when victims click the link.
5. Impact analysis
Confidentiality
- High. Reset tokens embedded in attacker-controlled links are easily exfiltrated by the attacker-controlled domain or intercepted over HTTP.
Integrity
- High. With a reset token an attacker can set a new password and take over the account (full account compromise).
Availability
- Low–Medium. Not typically an availability issue, but large-scale account takeover can lead to operational impacts.
Attack scenarios
-
Targeted account takeover: Attacker causes a reset email for a specific victim and captures the token.
-
Mass phishing: Attacker poisons links in mass reset flows or in cached pages to harvest tokens or credentials.
-
Network interception: Forcing
http://allows MITM on untrusted networks to observe tokens.
6. Root cause
-
Trusting a client-controlled header (
req.headers.host) when generating absolute URLs. -
Hardcoding the insecure scheme
http://rather than usinghttps://or a configurable canonical origin. -
Lack of allowlist validation for allowed hostnames or lack of a server-side canonical base URL configuration.
7. Remediation (actionable steps)
High-priority (apply immediately)
-
Stop using
req.headers.hostto build absolute links.Use a server-side configured canonical base URL stored in configuration/environment, and include the scheme (must be
https://).- Recommended env var:
BASE_URL=https://app.example.com
- Recommended env var:
-
Always generate HTTPS links.
Ensure the base URL uses
https://and that emails/links usehttps://.... Do not generatehttp://links for public-facing flows. -
Make tokens single-use and short-lived.
-
Token TTL: e.g., ≤ 1 hour (adjust to risk model).
-
Invalidate token after first use.
-
Record token issuance timestamp and revoke after expiry.
-
Example secure replacement (Node.js / Express)
// config.js
module.exports = {
BASE_URL: process.env.BASE_URL || 'https://app.example.com', // MUST include https://
RESET_TOKEN_TTL_SECONDS: 3600,
};
// reset-email.js
const { BASE_URL } = require('./config');
const { URL } = require('url');
function buildResetLink(token) {
// Safe: uses canonical BASE_URL, avoids req.headers.host
return new URL(`/reset-password/token/${encodeURIComponent(token)}`, BASE_URL).toString();
}If multi-tenant dynamic hosts are required
- Maintain a server-side allowlist mapping inbound
Hostvalues to canonical origins and only use allowlisted hosts to build links.
const allowedHosts = {
'tenant1.example.com': 'https://tenant1.example.com',
'tenant2.example.com': 'https://tenant2.example.com',
};
const rawHost = req.headers.host?.split(':')[0]; // strip port
const BASE_URL = allowedHosts[rawHost] || process.env.BASE_URL;
const magicLink = new URL(`/reset-password/token/${token}`, BASE_URL).toString();Additional hardening
-
Use short, unpredictable tokens (cryptographically secure random values, not predictable sequential IDs).
-
Consider server-side reference codes: email includes a short code that your server maps to a token without exposing raw token in the URL when possible.
-
Add logging and alerting for suspicious Host header values and unusual reset request patterns.
-
Audit and correct proxy/load-balancer configuration to canonicalize or strip client
Hostheaders where appropriate.
9. Remediation timeline & priorities
-
Immediate (0–72 hours):
-
Replace
req.headers.hostusage withBASE_URLconfig and ensurehttps://. -
Shorten token TTL and enforce single-use.
-
-
Short term (1 week):
-
Audit codebase for other
req.headers.host/ client-header usage. -
Add host allowlist logic if multi-tenant hostnames are expected.
-
-
Medium term (1 month):
-
Add monitoring/alerting on suspicious Host headers and mass reset events.
-
Run targeted pentests / red-team to validate fixes.
-
-
Long term:
-
Review other flows that generate absolute URLs (email invites, webhooks) and standardize on the
BASE_URLapproach. -
Harden proxy/load-balancer canonicalization.
-
10. Suggested disclosure notes for triage
-
This is an authentication-related vulnerability with high impact; treat as high priority.
-
Include remediation steps and request confirmation once the canonical base URL config and deployment changes are applied.
-
Ask security/ops team to audit proxies/load-balancers for header forwarding behavior.
11. References & further reading
-
OWASP — Host header attack guidance and mitigation (search OWASP for “Host header” or “Host header poisoning”).
-
OWASP — Authentication Cheat Sheet / Password Reset Guidance (search OWASP Authentication Cheat Sheet and Password Reset).
-
Node.js
URLclass (safe URL construction). -
General best-practices for password reset tokens: single-use, short TTL, cryptographically random values, and server-side lookup rather than exposing persistent secrets.
E