Public mode

No access to your tenant or devices. Every item links to its source. What this means

Sources need attention Customize Public modeDiscuss ChangeIntel on Discord

h3 before 2.0.1-rc.18 Open Redirect via redirectBack()

CVSS 4.0 5.3 MEDIUMCVSS 3.1 5.4 MEDIUMEUVD CVSS 4.0 5.3 CVSS 4.0 · [email protected] · Secondary 5.3 MEDIUMCVSS 3.1 · [email protected] · Secondary 5.4 MEDIUMCVSS_V3 Publisher rating MODERATEFixed by h3 2.0.1-rc.18KEV status unknown

cve-program · CVE-2026-86205

Published

h3 versions before 2.0.1-rc.18 contain an open redirect vulnerability in the redirectBack() utility that fails to sanitize protocol-relative paths in the Referer header pathname. Attackers can craft a same-origin URL with a double-slash path segment that passes origin validation but produces a Location header interpreted by browsers as a protocol-relative redirect to an external domain.

Read the publisher's advisory

euvd · EUVD-2026-72105

Published

h3 versions before 2.0.1-rc.18 contain an open redirect vulnerability in the redirectBack() utility that fails to sanitize protocol-relative paths in the Referer header pathname. Attackers can craft a same-origin URL with a double-slash path segment that passes origin validation but produces a Location header interpreted by browsers as a protocol-relative redirect to an external domain.

Read the publisher's advisory

nvd · CVE-2026-86205

Published

h3 versions before 2.0.1-rc.18 contain an open redirect vulnerability in the redirectBack() utility that fails to sanitize protocol-relative paths in the Referer header pathname. Attackers can craft a same-origin URL with a double-slash path segment that passes origin validation but produces a Location header interpreted by browsers as a protocol-relative redirect to an external domain.

Read the publisher's advisory

osv · GHSA-fp4x-ggrf-wmc6

Published

## Summary The `redirectBack()` utility in h3 validates that the `Referer` header shares the same origin as the request before using its pathname as the redirect `Location`. However, the pathname is not sanitized for protocol-relative paths (starting with `//`). An attacker can craft a same-origin URL with a double-slash path segment that passes the origin check but produces a `Location` header interpreted by browsers as a protocol-relative redirect to an external domain. ## Details The vulnerable code is in `src/utils/response.ts:89-97`: ```typescript export function redirectBack( event: H3Event, opts: { fallback?: string; status?: number; allowQuery?: boolean } = {}, ): HTTPResponse { const referer = event.req.headers.get("referer"); let location = opts.fallback ?? "/"; if (referer && URL.canParse(referer)) { const refererURL = new URL(referer); if (refererURL.origin === event.url.origin) { // BUG: pathname can be "//evil.com/path" which browsers interpret // as a protocol-relative URL location = refererURL.pathname + (opts.allowQuery ? refererURL.search : ""); } } return redirect(location, opts.status); } ``` The root cause is a discrepancy between how the WHATWG URL parser and browsers handle double-slash paths: 1. `new URL("http://target.com//evil.com/path").origin` → `"http://target.com"` — origin check **passes** 2. `new URL("http://target.com//evil.com/path").pathname` → `"//evil.com/path"` — extracted as redirect location 3. Browser receives `Location: //evil.com/path` → interprets as protocol-relative URL → **redirects to `evil.com`** **Attack scenario:** The attacker shares a link like `http://target.com//evil.com/page`. If the target application has catch-all routes (common in SPAs built with h3/Nitro), the app serves its page at that URL. When the user navigates to an endpoint calling `redirectBack()`, the browser sends `Referer: http://target.com//evil.com/page`. The origin check passes, and the user is redirected to `evil.com`, which can host a phishing page mimicking the target. ## PoC ```bash # 1. Create a minimal h3 app with redirectBack cat > /tmp/h3-redirect-poc.ts << 'SCRIPT' import { H3, redirectBack } from "h3"; const app = new H3(); app.post("/submit", (event) => redirectBack(event)); const res = await app.fetch(new Request("http://localhost/submit", { method: "POST", headers: { referer: "http://localhost//evil.com/steal" } })); console.log("Status:", res.status); console.log("Location:", res.headers.get("location")); // Expected: a same-origin path // Actual: "//evil.com/steal" — protocol-relative redirect to evil.com SCRIPT # 2. Verify URL parsing behavior node -e " const u = new URL('http://localhost//evil.com/steal'); console.log('origin:', u.origin); // http://localhost console.log('pathname:', u.pathname); // //evil.com/steal console.log('origin matches localhost:', u.origin === 'http://localhost'); // true " # Output: # origin: http://localhost # pathname: //evil.com/steal # origin matches localhost: true ``` ## Impact An attacker can redirect users from a trusted application to an attacker-controlled domain. This enables: - **Credential phishing**: Redirect to a lookalike login page to harvest credentials - **OAuth token theft**: In OAuth flows using `redirectBack()`, steal authorization codes by redirecting to an attacker's callback - **Trust exploitation**: Users see the initial link points to the trusted domain, lowering suspicion The vulnerability requires no authentication and affects any endpoint using `redirectBack()`. ## Recommended Fix Sanitize the extracted pathname to prevent protocol-relative URLs. In `src/utils/response.ts`, after extracting the pathname from the referer: ```typescript export function redirectBack( event: H3Event, opts: { fallback?: string; status?: number; allowQuery?: boolean } = {}, ): HTTPResponse { const referer = event.req.headers.get("referer"); let location = opts.fallback ?? "/"; if (referer && URL.canParse(referer)) { const refererURL = new URL(referer); if (refererURL.origin === event.url.origin) { let pathname = refererURL.pathname; // Prevent protocol-relative open redirect (e.g., "//evil.com") if (pathname.startsWith("//")) { pathname = "/" + pathname.replace(/^\/+/, ""); } location = pathname + (opts.allowQuery ? refererURL.search : ""); } } return redirect(location, opts.status); } ```

Read the publisher's advisory

Affected versions, risk and source history

cve-program · CVE-2026-86205

Published

h3

Vendor product

Publisher's version information

Shown as published. These rules are not interpreted as NuGet package version ranges.

{
                    "vendor": "h3js",
                    "product": "h3",
                    "defaultStatus": "unaffected",
                    "packageURL": "pkg:npm/h3",
                    "versions": [
                        {
                            "version": "2.0.1-rc.17",
                            "status": "affected",
                            "lessThan": "2.0.1-rc.18",
                            "versionType": "semver"
                        },
                        {
                            "version": "2.0.1-rc.18",
                            "status": "unaffected",
                            "versionType": "semver"
                        }
                    ]
                }

Original source record · Cite this exact observation · Complete original publisher JSON

euvd · EUVD-2026-72105

Published

EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON.

Original publisher date fields

datePublished: Sep 6, 2026, 12:00:25 PM

dateUpdated: Sep 8, 2026, 1:28:55 PM

No normalized affected-package data is projected for this source revision. The original publisher record may contain additional product and version evidence; this does not establish that a package is unaffected.

Original source record · Cite this exact observation · Complete original publisher JSON

nvd · CVE-2026-86205

Published

NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON.

Source analysis status: Awaiting Analysis

Weakness classifications: CWE-601

Original publisher date fields

published: 2026-09-06T12:17:15.277

lastModified: 2026-09-08T20:00:18.870

No normalized affected-package data is projected for this source revision. The original publisher record may contain additional product and version evidence; this does not establish that a package is unaffected.

Original source record · Cite this exact observation · Complete original publisher JSON

osv · GHSA-fp4x-ggrf-wmc6

Published

h3

npm

SEMVER · introduced 2.0.1-rc.17 → fixed 2.0.1-rc.18

1 versions listed as affected

2.0.1-rc.17

Original source record · Cite this exact observation · Complete original publisher JSON

ChangeIntel

An IT change radar: releases, security, known issues, retirements, documentation changes, and service status from public sources. Every item links to supporting evidence; dates and statuses can change after they are read.

Sources read 15 Nov 12:11 UTC · 256 of 275 readable · 252 fully read · documentation 469/469 current