CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-FP4X-GGRF-WMC6
6.1

GHSA-FP4X-GGRF-WMC6: Open Redirect via Protocol-Relative Paths in UnJS H3

Amit Schendel
Amit Schendel
Senior Security Researcher

Mar 23, 2026·6 min read·5 visits

PoC Available

Executive Summary (TL;DR)

The H3 `redirectBack()` function improperly handles protocol-relative paths in the `Referer` header. Attackers can supply a referer like `http://trusted.com//evil.com`, passing origin checks but resulting in a `Location: //evil.com` header that browsers interpret as a redirect to an external site.

A critical vulnerability in the UnJS H3 package allows attackers to bypass domain validation within the `redirectBack()` utility. By providing a maliciously crafted `Referer` header containing a protocol-relative path, attackers can force the application to issue an open redirect to an arbitrary external domain. This issue affects versions prior to v2.0.1-rc.18.

Vulnerability Overview

The UnJS H3 framework is a minimal HTTP framework for Node.js, extensively utilized within the Nuxt ecosystem. The framework exposes a redirectBack() utility function designed to safely redirect users back to the page specified in their Referer header. To prevent malicious redirection, this function validates that the origin of the Referer URL exactly matches the origin of the current request.

The vulnerability, classified under CWE-601 (URL Redirection to Untrusted Site), occurs because the validation logic fails to account for protocol-relative paths extracted from the WHATWG URL object. While the origin validation correctly ensures the protocol and hostname match the trusted application, the pathname property retains leading double slashes if provided in the input.

When this unvalidated pathname is concatenated and passed directly into the Location HTTP response header, the context shifts. Modern web browsers interpret a Location header beginning with // as a protocol-relative URL, instructing the browser to maintain the current scheme (e.g., HTTPS) but navigate to a completely different host. This bypasses the developer's intended domain restrictions.

Root Cause Analysis

The root cause of this vulnerability lies in an impedance mismatch between how the WHATWG URL constructor parses malformed paths and how web browsers interpret HTTP Location headers. When the native Node.js URL class processes a string like https://trusted-app.com//malicious-site.com/steal, it correctly identifies the protocol as https: and the host as trusted-app.com.

Because the host matches the expected origin, the application's security check (refererURL.origin === event.url.origin) evaluates to true. However, the URL constructor parses the remainder of the string, //malicious-site.com/steal, and assigns it to the pathname property without normalizing the leading slashes. The application then uses this raw pathname to construct the redirect destination.

According to RFC 3986, a path segment beginning with two slashes is a network-path reference, commonly known as a protocol-relative URL. When the server sets Location: //malicious-site.com/steal, the browser resolves this relative to the current scheme. If the user is browsing via HTTPS, the browser redirects the user to https://malicious-site.com/steal, effectively completing the Open Redirect attack.

Code Analysis and Patch Verification

In versions of H3 prior to v2.0.1-rc.18, the redirectBack() function extracts the pathname directly from the validated refererURL object and applies it to the Location header. The vulnerable code path assumes that since the origin is trusted, the associated path is inherently local and safe for redirection.

The patch introduced in commit 459a1c6593365b0810e9c502df7c3e82837321d7 introduces an explicit normalization step for the pathname string. The implementation now checks if the path begins with a protocol-relative sequence (//) and strips all leading slashes before prepending a single, safe forward slash.

// File: src/utils/response.ts
export function redirectBack(event, opts = {}) {
  // ... existing origin validation logic ...
  if (refererURL.origin === event.url.origin) {
    let pathname = refererURL.pathname;
    
    // PATCH: Sanitize protocol-relative paths
    if (pathname.startsWith("//")) {
      pathname = "/" + pathname.replace(/^\/+/, "");
    }
    
    location = pathname + (opts.allowQuery ? refererURL.search : "");
  }
  // ...
}

This regex-based fix (/^\/+/) is highly effective because it ensures that regardless of how many slashes an attacker injects (e.g., ///evil.com), the resulting path is strictly forced into an absolute path relative to the current origin (e.g., /evil.com). This completely neutralizes the protocol-relative behavior in the browser's Location parser.

Exploitation Methodology

Exploiting this Open Redirect requires an attacker to control the Referer header sent by the victim's browser. While browsers typically restrict direct manipulation of the Referer header via client-side scripts, an attacker can construct a malicious webpage that naturally generates the desired header when the victim clicks a link.

The attack begins by hosting a staging page that initiates a request to the vulnerable H3 application endpoint. The staging environment is configured to append the malicious protocol-relative payload to its URL structure, or the attacker crafts a direct link containing the payload structure if the application passes user-controlled parameters into the Referer generation.

The following proof-of-concept test case demonstrates the exact server-side behavior. When the malicious referer http://localhost//evil.com/steal is submitted, the unpatched server responds with an unsafe Location header.

it("prevents open redirect via protocol-relative path in referer", async () => {
  // Application endpoint using redirectBack
  t.app.post("/submit", (event) => redirectBack(event));
  
  const baseUrl = "http://localhost";
  const res = await t.fetch("/submit", {
    method: "POST",
    headers: { 
      referer: `${baseUrl}//evil.com/steal` 
    },
  });
 
  // Unpatched response returns Location: //evil.com/steal
  // Patched response returns Location: /evil.com/steal
});

Security Impact Assessment

The primary impact of this vulnerability is the facilitation of highly convincing phishing campaigns. Because the initial URL points to a trusted domain (the application running H3), users and email security filters are significantly more likely to trust the link. Once clicked, the application transparently forwards the user to an attacker-controlled destination.

Beyond basic phishing, Open Redirects often serve as chaining primitives in more complex attack sequences. If the vulnerable application utilizes OAuth or similar token-based authentication flows, an attacker can manipulate the redirect to hijack authorization codes or access tokens. By appending token fragments to the redirected URL, the attacker captures sensitive credentials on their own infrastructure.

The vulnerability is assessed with a CVSS 3.1 score of 6.1 (Medium). The attack vector is Network (AV:N) with Low attack complexity (AC:L), requiring no specialized privileges (PR:N). However, it strictly requires User Interaction (UI:R) and affects the changed scope of the user's browsing session (S:C), leading to low impacts on Confidentiality and Integrity (C:L/I:L).

Remediation and Mitigation Strategies

The definitive remediation for this vulnerability is upgrading the h3 package to version v2.0.1-rc.18 or later. Development teams should audit their package.json or package-lock.json files to ensure all transitive dependencies utilizing h3 are updated to incorporate the patched logic.

For environments where immediate patching is not technically feasible, a temporary mitigation involves deploying middleware or a Web Application Firewall (WAF) rule to intercept and sanitize incoming requests. Specifically, rules should inspect the Referer header and reject or rewrite any requests where the pathname segment begins with multiple forward slashes.

Developers utilizing redirectBack() should also review their application architecture to determine if relying on the Referer header is strictly necessary. Implementing stateful redirection flows using server-side session variables or signed redirect tokens provides a more robust defense-in-depth posture against redirection attacks.

Official Patches

UnJSOfficial fix commit in h3 repository
UnJSRelease v2.0.1-rc.18 containing the patch

Fix Analysis (1)

Technical Appendix

CVSS Score
6.1/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N

Affected Systems

Node.js ApplicationsUnJS H3 FrameworkNuxt Framework (depending on H3 version)

Affected Versions Detail

Product
Affected Versions
Fixed Version
h3
UnJS
< v2.0.1-rc.18v2.0.1-rc.18
AttributeDetail
Vulnerability ClassOpen Redirect (CWE-601)
CVSS v3.1 Score6.1 (Medium)
Attack VectorNetwork
Authentication RequiredNone
User InteractionRequired
Affected ComponentredirectBack() utility
Exploit StatusProof of Concept Available

MITRE ATT&CK Mapping

T1204.001User Execution: Malicious Link
Execution
CWE-601
URL Redirection to Untrusted Site ('Open Redirect')

A web application accepts a user-controlled input that specifies a link to an external site, and uses that link in a Redirect. This simplifies phishing attacks.

Vulnerability Timeline

Patch released in h3 version v2.0.1-rc.18
2026-03-21

References & Sources

  • [1]GitHub Advisory: GHSA-FP4X-GGRF-WMC6
  • [2]Fix Commit in UnJS/H3
  • [3]Release v2.0.1-rc.18

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.