Express.js is the most widely used web framework in the Node.js ecosystem, sitting underneath a huge share of production APIs and server-rendered applications. In April 2024, the Express maintainers disclosed CVE-2024-29041, an open redirect vulnerability affecting res.location() and res.redirect() in Express versions prior to 4.19.2. The flaw allows an attacker to craft a malformed URL that Express's built-in host-validation logic fails to recognize as absolute, causing the application to redirect a victim's browser to an attacker-controlled destination even when the developer believed they were validating redirect targets. The practical impact is phishing and credential-theft campaigns that inherit the trust of a legitimate domain — a user clicks a link to a known, trusted site and is silently bounced to a malicious lookalike page, often used to harvest credentials, deliver malware, or bypass OAuth/SSO trust checks that key off the originating hostname.
Open redirects rarely make headlines the way remote code execution does, but they are a favorite primitive in real-world phishing kits precisely because they abuse a domain's reputation. When the vulnerable code path sits inside a framework as ubiquitous as Express, the blast radius is every application, gateway, and internal tool built on top of it that never patched — which, given how deeply Express is vendored into other frameworks and starter kits, is a larger population than most security teams assume.
Affected Versions and Components
CVE-2024-29041 affects the Express.js express npm package, specifically the request-handling logic backing:
res.redirect(url)res.location(url)
Vulnerable releases: all Express 4.x versions prior to 4.19.2.
Fixed in: Express 4.19.2, released April 20, 2024.
The root cause lives in how Express determines whether a supplied redirect target is a relative path (safe, stays on the same host) or an absolute URL (potentially attacker-controlled). Prior to the fix, certain malformed inputs — strings that mix backslashes, malformed scheme separators, or other characters that Node's URL parser and browsers interpret inconsistently — could slip past Express's internal check and be treated as relative when a browser would actually resolve them as absolute, off-domain URLs. Applications are exposed whenever attacker-influenced input (a query parameter, a next/returnTo field, a referer-derived value, etc.) is passed into res.redirect() or res.location() without the application performing its own allow-list validation. Express applications that never pass user-controlled data into these methods are not affected, and applications that already enforce a strict allow-list of permitted redirect destinations are substantially less exposed, though upgrading remains recommended defense-in-depth.
Because Express underpins a long list of downstream frameworks, meta-frameworks, admin panels, and internal tooling, transitive exposure is common. Teams should check not just their own direct package.json but every service, generator template, and vendored middleware bundle that pulls in Express as a dependency.
CVSS, EPSS, and KEV Context
- CVSS v3.1 base score: 6.1 (Medium), reflecting a network-exploitable, low-complexity issue that requires user interaction (the victim has to click the crafted link) and yields low-confidentiality/low-integrity impact rather than direct data compromise.
- EPSS: exploitation-probability scoring for this CVE has remained low relative to the broader vulnerability population, consistent with the general pattern for open redirects — they are useful phishing infrastructure but are rarely the headline exploit chain step that automated scanners and mass-exploitation campaigns key off of. Treat any specific EPSS percentile as a snapshot; check current values in your vulnerability intelligence feed rather than relying on a static number, since EPSS is recalculated continuously.
- CISA KEV: as of this writing, CVE-2024-29041 is not listed in CISA's Known Exploited Vulnerabilities catalog. That is not a reason to deprioritize it — KEV listing lags real-world abuse, and open redirects are routinely folded into phishing kits and business-email-compromise infrastructure without ever generating the kind of visible incident telemetry that drives a KEV addition.
The practical takeaway for triage: this is not a "drop everything" critical, but it is a cheap, low-friction fix that removes a real phishing enabler, and it should be picked up in the same patch cycle as your other Express dependency bumps rather than deferred indefinitely.
Timeline
- Disclosure and coordination: the vulnerability was reported to the Express project maintainers through their responsible disclosure process ahead of public release.
- April 2024: the Express maintainers published GitHub Security Advisory GHSA-rv95-896h-c2vc, detailing the open redirect behavior in
res.location()andres.redirect(). - April 20, 2024: Express 4.19.2 shipped, correcting the URL-parsing logic that allowed malformed inputs to bypass the relative/absolute host check.
- Shortly after: MITRE/NVD assigned CVE-2024-29041, and the fix propagated through the npm advisory database, GitHub Dependabot alerts, and downstream SCA tooling.
No evidence of pre-disclosure in-the-wild exploitation has been publicly confirmed for this specific CVE, but given the low cost of weaponizing an open redirect vulnerability and the ubiquity of Express, defenders should assume opportunistic scanning for unpatched instances began quickly after public disclosure — this is a common pattern once a well-known framework's advisory and diff are public.
Remediation Steps
- Upgrade Express to 4.19.2 or later (or the current Express 5.x line, which includes the corrected logic). This is a non-breaking patch release for the vast majority of applications — run your existing test suite after upgrading and treat any redirect-handling tests as high priority.
npm install express@^4.19.2 - Inventory every redirect call site. Search your codebase for
res.redirect(andres.location(and identify which ones receive any attacker-influenced input — query strings, form fields, headers, or values derived from them (e.g., areturnTo,next, orredirect_uriparameter used in login flows). - Apply allow-list validation independent of the framework patch. Even after upgrading, don't rely solely on Express's internal parsing to be the last line of defense. Validate that redirect targets are either relative paths beginning with a single
/(and not//or/\, both of which browsers can treat as protocol-relative absolute URLs) or match an explicit allow-list of trusted hostnames before callingres.redirect(). - Check vendored and transitive Express usage. If you maintain internal frameworks, admin dashboards, or generator templates that pin an older Express version, patch those templates too — a fixed direct dependency doesn't help if a vendored copy or an internal library still ships the vulnerable version.
- Regenerate and diff your SBOM after patching to confirm the updated Express version is actually reflected in what ships to production, not just in
package.json— lockfile drift and container image caching are common reasons a "patched" dependency tree still ships the old binary. - Add a regression test that asserts your login/redirect flows reject malformed absolute-URL-style inputs (backslash variants, protocol-relative
//, and mixed-case scheme tricks), so a future dependency downgrade or refactor doesn't silently reopen the gap.
How Safeguard Helps
Safeguard is built to cut through exactly this kind of triage ambiguity. Our SBOM generation and ingest pipeline continuously maps every service — including transitive and vendored Express instances — against the NVD and GHSA advisory feeds, so CVE-2024-29041 surfaces automatically the moment a vulnerable version is present anywhere in your fleet, not just in your top-level manifests. Rather than stopping at "Express is present," Safeguard's reachability analysis traces whether your application actually calls res.redirect() or res.location() with attacker-influenced input, letting your team prioritize the handful of genuinely exploitable services over the much larger set of theoretically-affected ones. Griffin AI, Safeguard's contextual risk engine, layers in the CVSS, EPSS, and KEV signals discussed above alongside your own exposure posture to produce a single, defensible priority score instead of a raw CVE count. And when it's time to act, Safeguard can open an auto-fix pull request that bumps Express to the patched release across every affected repository, so remediation becomes a review-and-merge task rather than a manual hunt through dozens of package.json files.