{"id":"CVE-2026-23527","aliases":["GHSA-mp2g-9vg9-f4cg"],"url":"https://o3.security/vulnerability/CVE-2026-23527","summary":"h3 v1 has Request Smuggling (TE.TE) issue","details":"I was digging into h3 v1 (specifically v1.15.4) and found a critical HTTP Request Smuggling vulnerability.\n\nBasically, `readRawBody` is doing a strict case-sensitive check for the Transfer-Encoding header. It explicitly looks for \"chunked\", but per the RFC, this header should be case-insensitive.\n\n**The Bug**: If I send a request with Transfer-Encoding: ChuNked (mixed case), h3 misses it. Since it doesn't see \"chunked\" and there's no Content-Length, it assumes the body is empty and processes the request immediately.\n\nThis leaves the actual body sitting on the socket, which triggers a classic TE.TE Desync (Request Smuggling) if the app is running behind a Layer 4 proxy or anything that doesn't normalize headers (like AWS NLB or Node proxies).\n\n**Vulnerable Code** (`src/utils/body.ts`):\n\n```js\nif (\n    !Number.parseInt(event.node.req.headers[\"content-length\"] || \"\") &&\n    !String(event.node.req.headers[\"transfer-encoding\"] ?? \"\")\n      .split(\",\")\n      .map((e) => e.trim())\n      .filter(Boolean)\n      .includes(\"chunked\") // <--- This is the issue. \"ChuNkEd\" returns false here.\n  ) {\n    return Promise.resolve(undefined);\n  }\n```\n\nI verified this locally:\n\n- Sent a `Transfer-Encoding: ChunKed` request without a closing 0 chunk.\n- Express hangs (correctly waiting for data).\n- h3 responds immediately (vulnerable, thinks body is length 0).\n\n**Impact**: Since H3/Nuxt/Nitro is often used in containerized setups behind TCP load balancers, an attacker can use this to smuggle requests past WAFs or desynchronize the socket to poison other users' connections.\n\n**Fix**: Just need to normalize the header value before checking: ` .map((e) => e.trim().toLowerCase())`","published":"2026-01-15T19:24:20.514Z","modified":"2026-08-12T03:51:17.366498279Z","cvss":{"score":8.9,"severity":"HIGH","vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:L"},"epss":{"score":0.00586,"percentile":0.45387,"asOf":"2026-08-24"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"npm","name":"h3","fixedVersion":"1.15.5"}],"fix":{"url":"https://github.com/h3js/h3/commit/618ccf4f37b8b6148bea7f36040471af45bfb097","label":"h3js/h3@618ccf4"},"references":[{"type":"WEB","url":"https://github.com/h3js/h3/releases/tag/v1.15.5"},{"type":"WEB","url":"https://simonkoeck.com/writeups/h3-transfer-encoding-request-smuggling"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/23xxx/CVE-2026-23527.json"},{"type":"ADVISORY","url":"https://github.com/h3js/h3/security/advisories/GHSA-mp2g-9vg9-f4cg"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-23527"},{"type":"FIX","url":"https://github.com/h3js/h3/commit/618ccf4f37b8b6148bea7f36040471af45bfb097"},{"type":"PACKAGE","url":"https://github.com/h3js/h3"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:17.366498279Z"}}