h3
Ecosystem: npm
Downloads: 142.73 Mln
- 0CriticalAffects 0 versions
- 4HighAffects 5 versions
- 0MediumAffects 0 versions
- 6ModerateAffects 8 versions
- 1LowAffects 1 version
- Critical0 (0.0%)
- High4 (36.4%)
- Medium0 (0.0%)
- Moderate6 (54.5%)
- Low1 (9.1%)
Monthly breakdown
- Critical
- High
- Medium
- Moderate
- Low
- 1 vulnerabilities
- Critical: 0
- High: 1
- Medium: 0
- Moderate: 0
- Low: 0
- 9 vulnerabilities
- Critical: 0
- High: 2
- Medium: 0
- Moderate: 6
- Low: 1
- 1 vulnerabilities
- Critical: 0
- High: 1
- Medium: 0
- Moderate: 0
- Low: 0
Vulnerabilities (11)
Known vulnerabilities affecting h3, based on data from OSV.
| ID | Severity | Summary | Affected versions | Published | Source |
|---|---|---|---|---|---|
| GHSA-fg72-q65g-wm5w | High | Duplicate Advisory: H3: Unbounded Chunked Cookie Count in Session Cleanup Loop may Lead to Denial of Service## Duplicate Advisory This advisory has been withdrawn because it is a duplicate of GHSA-q5pr-72pq-83v3. This link is maintained to preserve external references. ## Original Description h3 versions before 2.0.1-rc.18 fail to validate the chunk count parsed from user-controlled cookie values in setChunkedCookie() and deleteChunkedCookie() functions. Attackers can send a crafted cookie header with an extremely large chunk count to trigger an O(n²) cleanup loop that hangs the server process. |
| GitHub (opens in a new tab) | |
| GHSA-fp4x-ggrf-wmc6 | Moderate | H3 has an Open Redirect via Protocol-Relative Path in redirectBack() Referer Validation## 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 |
| GitHub (opens in a new tab) | |
| GHSA-q5pr-72pq-83v3 | Moderate | H3: Unbounded Chunked Cookie Count in Session Cleanup Loop may Lead to Denial of Service## Summary The `setChunkedCookie()` and `deleteChunkedCookie()` functions in h3 trust the chunk count parsed from a user-controlled cookie value (`__chunked__N`) without any upper bound validation. An unauthenticated attacker can send a single request with a crafted cookie header (e.g., `Cookie: h3=__chunked__999999`) to any endpoint using sessions, causing the server to enter an O(n²) loop that hangs the process. ## Details The chunked cookie system stores large cookie values by splitting them into numbered chunks. The main cookie stores a sentinel value `__chunked__N` indicating how many |
| GitHub (opens in a new tab) | |
| GHSA-2j6q-whv2-gh6w | Low | h3: Missing Path Segment Boundary Check in `mount()` Causes Middleware Execution on Unrelated Prefix-Matching Routes## Summary The `mount()` method in h3 uses a simple `startsWith()` check to determine whether incoming requests fall under a mounted sub-application's path prefix. Because this check does not verify a path segment boundary (i.e., that the next character after the base is `/` or end-of-string), middleware registered on a mount like `/admin` will also execute for unrelated routes such as `/admin-public`, `/administrator`, or `/adminstuff`. This allows an attacker to trigger context-setting middleware on paths it was never intended to cover, potentially polluting request context with unintended |
| GitHub (opens in a new tab) | |
| GHSA-4hxc-9384-m385 | Moderate | h3: SSE Event Injection via Unsanitized Carriage Return (`\r`) in EventStream Data and Comment Fields (Bypass of CVE Fix)## Summary The `EventStream` class in h3 fails to sanitize carriage return (`\r`) characters in `data` and `comment` fields. Per the SSE specification, `\r` is a valid line terminator, so browsers interpret injected `\r` as line breaks. This allows an attacker to inject arbitrary SSE events, spoof event types, and split a single `push()` call into multiple distinct browser-parsed events. This is an incomplete fix bypass of commit `7791538` which addressed `\n` injection but missed `\r`-only injection. ## Details The prior fix in commit `7791538` added `_sanitizeSingleLine()` to strip `\n` a |
| GitHub (opens in a new tab) | |
| GHSA-72gr-qfp7-vwhw | Moderate | h3: Double Decoding in `serveStatic` Bypasses `resolveDotSegments` Path Traversal Protection via `%252e%252e`## Summary The `serveStatic` utility in h3 applies a redundant `decodeURI()` call to the request pathname after `H3Event` has already performed percent-decoding with `%25` preservation. This double decoding converts `%252e%252e` into `%2e%2e`, which bypasses `resolveDotSegments()` (since it checks for literal `.` characters, not percent-encoded equivalents). When the resulting asset ID is resolved by URL-based backends (CDN, S3, object storage), `%2e%2e` is interpreted as `..` per the URL Standard, enabling path traversal to read arbitrary files from the backend. ## Details The vulnerabilit |
| GitHub (opens in a new tab) | |
| GHSA-22cc-p3c6-wpvm | High | h3 has a Server-Sent Events Injection via Unsanitized Newlines in Event Stream Fields## Summary `createEventStream` in h3 is vulnerable to Server-Sent Events (SSE) injection due to missing newline sanitization in `formatEventStreamMessage()` and `formatEventStreamComment()`. An attacker who controls any part of an SSE message field (`id`, `event`, `data`, or comment) can inject arbitrary SSE events to connected clients. ## Details The vulnerability exists in `src/utils/internal/event-stream.ts`, lines [170](https://github.com/h3js/h3/blob/52c82e18bb643d124b8b9ec3b1f62b081f044611/src/utils/internal/event-stream.ts#L170)-[187](https://github.com/h3js/h3/blob/52c82e18bb643d124 |
| GitHub (opens in a new tab) | |
| GHSA-26f5-8h2x-34xh | Moderate | h3 has an observable timing discrepancy in basic auth utils### Summary A Timing Side-Channel vulnerability exists in the `requireBasicAuth` function due to the use of unsafe string comparison (`!==`). This allows an attacker to deduce the valid password character-by-character by measuring the server's response time, effectively bypassing password complexity protections. ### Details The vulnerability is located in the `requireBasicAuth` function. The code performs a standard string comparison between the user-provided password and the expected password: ~~~typescript if (opts.password && password !== opts.password) { throw autheFailed(event, opts?. |
| GitHub (opens in a new tab) | |
| GHSA-3vj8-jmxq-cgj5 | High | h3 has a middleware bypass with one gadget# H3 NodeRequestUrl bugs Vulnerable pieces of code : ```js 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 |
| GitHub (opens in a new tab) | |
| GHSA-wr4h-v87w-p3r7 | Moderate | h3 has a Path Traversal via Percent-Encoded Dot Segments in serveStatic Allows Arbitrary File Read## Summary `serveStatic()` in h3 is vulnerable to path traversal via percent-encoded dot segments (`%2e%2e`), allowing an unauthenticated attacker to read arbitrary files outside the intended static directory on Node.js deployments. ## Details The vulnerability exists in `src/utils/static.ts` at [line 86](https://github.com/h3js/h3/blob/52c82e18bb643d124b8b9ec3b1f62b081f044611/src/utils/static.ts#L86): ```typescript const originalId = decodeURI(withLeadingSlash(withoutTrailingSlash(event.url.pathname))); ``` On Node.js, h3 uses srvx's `FastURL` class to parse request URLs. Unlike the stan |
| GitHub (opens in a new tab) |
- GHSA-fg72-q65g-wm5wHighDuplicate Advisory: H3: Unbounded Chunked Cookie Count in Session Cleanup Loop may Lead to Denial of Service
>= 2.0.0-beta.4
## Duplicate Advisory This advisory has been withdrawn because it is a duplicate of GHSA-q5pr-72pq-83v3. This link is maintained to preserve external references. ## Original Description h3 versions before 2.0.1-rc.18 fail to validate the chunk count parsed from user-controlled cookie values in setChunkedCookie() and deleteChunkedCookie() functions. Attackers can send a crafted cookie header with an extremely large chunk count to trigger an O(n²) cleanup loop that hangs the server process.
- GHSA-fp4x-ggrf-wmc6ModerateH3 has an Open Redirect via Protocol-Relative Path in redirectBack() Referer Validation
>= 2.0.1-rc.17, < 2.0.1-rc.18
## 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
CVE: CVE-2026-86205
- GHSA-q5pr-72pq-83v3ModerateH3: Unbounded Chunked Cookie Count in Session Cleanup Loop may Lead to Denial of Service
>= 2.0.0-beta.4, < 2.0.1-rc.18
## Summary The `setChunkedCookie()` and `deleteChunkedCookie()` functions in h3 trust the chunk count parsed from a user-controlled cookie value (`__chunked__N`) without any upper bound validation. An unauthenticated attacker can send a single request with a crafted cookie header (e.g., `Cookie: h3=__chunked__999999`) to any endpoint using sessions, causing the server to enter an O(n²) loop that hangs the process. ## Details The chunked cookie system stores large cookie values by splitting them into numbered chunks. The main cookie stores a sentinel value `__chunked__N` indicating how many
CVE: CVE-2026-86250
- GHSA-2j6q-whv2-gh6wLowh3: Missing Path Segment Boundary Check in `mount()` Causes Middleware Execution on Unrelated Prefix-Matching Routes
>= 2.0.1-alpha.0, < 2.0.1-rc.17
## Summary The `mount()` method in h3 uses a simple `startsWith()` check to determine whether incoming requests fall under a mounted sub-application's path prefix. Because this check does not verify a path segment boundary (i.e., that the next character after the base is `/` or end-of-string), middleware registered on a mount like `/admin` will also execute for unrelated routes such as `/admin-public`, `/administrator`, or `/adminstuff`. This allows an attacker to trigger context-setting middleware on paths it was never intended to cover, potentially polluting request context with unintended
CVE: CVE-2026-33490
- GHSA-4hxc-9384-m385Moderateh3: SSE Event Injection via Unsanitized Carriage Return (`\r`) in EventStream Data and Comment Fields (Bypass of CVE Fix)
>= 2.0.0-beta.0, < 2.0.1-rc.17< 1.15.9
## Summary The `EventStream` class in h3 fails to sanitize carriage return (`\r`) characters in `data` and `comment` fields. Per the SSE specification, `\r` is a valid line terminator, so browsers interpret injected `\r` as line breaks. This allows an attacker to inject arbitrary SSE events, spoof event types, and split a single `push()` call into multiple distinct browser-parsed events. This is an incomplete fix bypass of commit `7791538` which addressed `\n` injection but missed `\r`-only injection. ## Details The prior fix in commit `7791538` added `_sanitizeSingleLine()` to strip `\n` a
CVE: CVE-2026-86252
- GHSA-72gr-qfp7-vwhwModerateh3: Double Decoding in `serveStatic` Bypasses `resolveDotSegments` Path Traversal Protection via `%252e%252e`
< 1.15.9
## Summary The `serveStatic` utility in h3 applies a redundant `decodeURI()` call to the request pathname after `H3Event` has already performed percent-decoding with `%25` preservation. This double decoding converts `%252e%252e` into `%2e%2e`, which bypasses `resolveDotSegments()` (since it checks for literal `.` characters, not percent-encoded equivalents). When the resulting asset ID is resolved by URL-based backends (CDN, S3, object storage), `%2e%2e` is interpreted as `..` per the URL Standard, enabling path traversal to read arbitrary files from the backend. ## Details The vulnerabilit
CVE: CVE-2026-86251
- GHSA-22cc-p3c6-wpvmHighh3 has a Server-Sent Events Injection via Unsanitized Newlines in Event Stream Fields
>= 2.0.0, < 2.0.1-rc.15< 1.15.6
## Summary `createEventStream` in h3 is vulnerable to Server-Sent Events (SSE) injection due to missing newline sanitization in `formatEventStreamMessage()` and `formatEventStreamComment()`. An attacker who controls any part of an SSE message field (`id`, `event`, `data`, or comment) can inject arbitrary SSE events to connected clients. ## Details The vulnerability exists in `src/utils/internal/event-stream.ts`, lines [170](https://github.com/h3js/h3/blob/52c82e18bb643d124b8b9ec3b1f62b081f044611/src/utils/internal/event-stream.ts#L170)-[187](https://github.com/h3js/h3/blob/52c82e18bb643d124
CVE: CVE-2026-33128
- GHSA-26f5-8h2x-34xhModerateh3 has an observable timing discrepancy in basic auth utils
>= 2.0.0-beta.0, < 2.0.1-rc.9
### Summary A Timing Side-Channel vulnerability exists in the `requireBasicAuth` function due to the use of unsafe string comparison (`!==`). This allows an attacker to deduce the valid password character-by-character by measuring the server's response time, effectively bypassing password complexity protections. ### Details The vulnerability is located in the `requireBasicAuth` function. The code performs a standard string comparison between the user-provided password and the expected password: ~~~typescript if (opts.password && password !== opts.password) { throw autheFailed(event, opts?.
CVE: CVE-2026-33129
- GHSA-3vj8-jmxq-cgj5Highh3 has a middleware bypass with one gadget
>= 2.0.0-0, < 2.0.1-rc.15
# H3 NodeRequestUrl bugs Vulnerable pieces of code : ```js 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
CVE: CVE-2026-33131
- GHSA-wr4h-v87w-p3r7Moderateh3 has a Path Traversal via Percent-Encoded Dot Segments in serveStatic Allows Arbitrary File Read
>= 2.0.0, < 2.0.1-rc.15< 1.15.6
## Summary `serveStatic()` in h3 is vulnerable to path traversal via percent-encoded dot segments (`%2e%2e`), allowing an unauthenticated attacker to read arbitrary files outside the intended static directory on Node.js deployments. ## Details The vulnerability exists in `src/utils/static.ts` at [line 86](https://github.com/h3js/h3/blob/52c82e18bb643d124b8b9ec3b1f62b081f044611/src/utils/static.ts#L86): ```typescript const originalId = decodeURI(withLeadingSlash(withoutTrailingSlash(event.url.pathname))); ``` On Node.js, h3 uses srvx's `FastURL` class to parse request URLs. Unlike the stan
CVE: CVE-2026-86253