{
  "schemaVersion": "guard-threat-campaign/v1",
  "id": "HGTC-2026-D248E742",
  "slug": "cve-2026-111497-nodejs-brotli-decoder-out-of-bounds-write",
  "title": "Node.js Brotli decoder writes out of bounds on a malformed stream, reachable through fetch(), Express 5 and zlib (CVE-2026-111497)",
  "aliases": [
    "CVE-2026-111497",
    "Node.js Brotli RCE",
    "Node.js Brotli decoder out-of-bounds write",
    "Node.js October 2026 security release",
    "Brotli 1.2.1 security fix",
    "BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH"
  ],
  "summary": "CVE-2026-111497 is an out-of-bounds write in the Brotli decoder that Node.js bundles in deps/brotli. The Node.js project rates it high and describes the impact as remote code execution; it affects the 26.x, 24.x and 22.x lines, and end-of-life lines are always affected. Node.js fixed it on 2026-10-21 in 22.23.4, 24.22.1 and 26.12.1 by cherry-picking upstream Brotli commit 0ed4268a ('Detect and report invalid stream earlier'). In the old code, a stream that declared a single block type and then requested a block switch made DecodeBlockTypeAndLength return false, but on the fast decoding path the block-switch wrappers were void functions, so the failure was ignored and decoding continued. The fix returns the new error BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH (-17) and stops. Node exposes that constant in zlib.constants, which gives operators a one-line patched/unpatched check. Exposure comes from any code that decodes attacker-influenced Brotli: fetch() (undici) decodes Content-Encoding: br responses, body-parser 2.x (Express 5) decodes br request bodies by default, axios requests br by default, and direct zlib Brotli decompression calls. Brotli itself shipped the fix in 1.2.1, 1.1.1 and 1.0.10 on 2026-10-21.",
  "status": "published",
  "severity": "high",
  "confidence": "high",
  "uncertainty": "The CVE record and NVD entry were not public at campaign creation, so there is no CVSS vector or CWE from NVD. Sources differ on demonstrated impact: The Hacker News reports the public proof of concept reached code execution only on a deliberately weakened build, with a crash and limited memory read on a standard build; Vercel's bulletin says researchers demonstrated memory disclosure and command execution on unpatched 22.x, 24.x and 26.x. No exploitation in the wild has been reported and the CVE is not in the CISA KEV catalog as of 2026-10-22.",
  "firstObservedAt": "2026-10-21T00:00:00Z",
  "lastObservedAt": "2026-10-22T09:51:27Z",
  "publishedAt": "2026-10-22T09:57:35.971Z",
  "reviewedAt": "2026-10-22T09:57:28.259Z",
  "expiresAt": "2026-10-22T09:51:27Z",
  "reviewer": "HOL Guard Security Publishing",
  "sources": [
    {
      "id": "node-advisory",
      "label": "Node.js: Wednesday, October 21, 2026 Security Releases",
      "url": "https://nodejs.org/en/blog/vulnerability/october-2026-security-releases",
      "sourceType": "vendor_advisory",
      "observedAt": "2026-10-21T00:00:00Z"
    },
    {
      "id": "node-release-v24",
      "label": "Node.js 24.22.1 (LTS) release notes",
      "url": "https://nodejs.org/en/blog/release/v24.22.1",
      "sourceType": "vendor_advisory",
      "observedAt": "2026-10-21T00:00:00Z"
    },
    {
      "id": "node-brotli-commit",
      "label": "nodejs/node 49dff6f57a: deps: brotli: cherry-pick 0ed4268a4401abcb44720963 (CVE-2026-111497)",
      "url": "https://github.com/nodejs/node/commit/49dff6f57a",
      "sourceType": "maintainer_advisory",
      "observedAt": "2026-10-21T00:00:00Z"
    },
    {
      "id": "node-constant-commit",
      "label": "nodejs/node b5f41529df: src: expose BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH",
      "url": "https://github.com/nodejs/node/commit/b5f41529df",
      "sourceType": "maintainer_advisory",
      "observedAt": "2026-10-21T00:00:00Z"
    },
    {
      "id": "brotli-changelog",
      "label": "Brotli 1.2.1 changelog (CVE-2026-111497)",
      "url": "https://github.com/google/brotli/blob/v1.2.1/CHANGELOG.md",
      "sourceType": "maintainer_advisory",
      "observedAt": "2026-10-21T00:00:00Z"
    },
    {
      "id": "vercel-bulletin",
      "label": "Vercel: Node.js security advisory, Brotli decoder RCE (CVE-2026-111497)",
      "url": "https://vercel.com/kb/bulletin/node-js-security-advisory",
      "sourceType": "vendor_advisory",
      "observedAt": "2026-10-21T00:00:00Z"
    },
    {
      "id": "thn",
      "label": "The Hacker News: Node.js Brotli decoder bug could allow remote code execution",
      "url": "https://thehackernews.com/2026/10/nodejs-brotli-decoder-bug-could-allow.html",
      "sourceType": "research",
      "observedAt": "2026-10-22T00:00:00Z"
    },
    {
      "id": "hol-blog",
      "label": "HOL blog: Node.js CVE-2026-111497 operator write-up",
      "url": "https://hol.org/blog/cve-2026-111497-nodejs-brotli-decoder-out-of-bounds-write",
      "sourceType": "other_primary",
      "observedAt": "2026-10-22T09:51:27Z"
    }
  ],
  "artifacts": [
    {
      "id": "nodejs-runtime",
      "artifactClass": "package",
      "ecosystem": "nodejs-runtime",
      "name": "Node.js",
      "version": "<22.23.4 || >=24.0.0 <24.22.1 || >=26.0.0 <26.12.1 (all EOL lines affected, no fix)",
      "defanged": false
    },
    {
      "id": "google-brotli",
      "artifactClass": "remote_dependency",
      "ecosystem": "c",
      "name": "google/brotli decoder (bundled as deps/brotli)",
      "version": "<1.0.10 || >=1.1.0 <1.1.1 || >=1.2.0 <1.2.1",
      "defanged": false
    }
  ],
  "indicators": [],
  "timeline": [
    {
      "id": "brotli-upstream-commit",
      "occurredAt": "2026-02-27T13:10:32Z",
      "eventType": "vendor_action",
      "summary": "Google Brotli commits 0ed4268a 'Detect and report invalid stream earlier', adding BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH.",
      "sourceIds": [
        "node-brotli-commit",
        "thn"
      ]
    },
    {
      "id": "node-security-release",
      "occurredAt": "2026-10-21T00:00:00Z",
      "eventType": "vendor_action",
      "summary": "Node.js releases 22.23.4, 24.22.1 and 26.12.1 fixing CVE-2026-111497 (high) and nine other CVEs.",
      "sourceIds": [
        "node-advisory",
        "node-release-v24"
      ]
    },
    {
      "id": "brotli-security-release",
      "occurredAt": "2026-10-21T00:00:00Z",
      "eventType": "vendor_action",
      "summary": "Brotli ships 1.2.1 (with 1.1.1 and 1.0.10) listing CVE-2026-111497 as a security fix.",
      "sourceIds": [
        "brotli-changelog",
        "thn"
      ]
    },
    {
      "id": "vercel-waf-rules",
      "occurredAt": "2026-10-21T00:00:00Z",
      "eventType": "vendor_action",
      "summary": "Vercel deploys WAF rules blocking the inbound vector and rolls patched runtimes; fetched responses are not covered by the WAF.",
      "sourceIds": [
        "vercel-bulletin"
      ]
    },
    {
      "id": "public-poc-reported",
      "occurredAt": "2026-10-22T00:00:00Z",
      "eventType": "disclosure",
      "summary": "The Hacker News reports a public proof of concept that reached code execution only on a deliberately weakened build; standard builds showed a crash and limited memory read.",
      "sourceIds": [
        "thn"
      ]
    },
    {
      "id": "hol-writeup",
      "occurredAt": "2026-10-22T09:51:27Z",
      "eventType": "other",
      "summary": "HOL publishes the operator write-up with exposure paths, the zlib.constants patch check and scope notes.",
      "sourceIds": [
        "hol-blog"
      ]
    }
  ],
  "coverage": [
    {
      "assertionId": "guard-not-runtime",
      "relationship": "not_covered",
      "limitation": "HOL Guard reviews AI coding agent actions on developer machines. It does not patch or sit inside the Node.js runtime and does not block malformed Brotli streams; the fix is the Node.js upgrade."
    }
  ],
  "policies": [],
  "limitations": [
    "Code that only compresses with Brotli is not the entry point; the patch touches the decoder only",
    "Apps that never decode attacker-reachable Brotli are far less exposed",
    "Vercel-managed functions on 22.x or 24.x are patched by Vercel; Node 20 projects must change version",
    "Browser-side JavaScript uses the browser's Brotli, not Node's",
    "Node.js 20 and older are affected and receive no fix",
    "Other software bundling its own Brotli decoder needs its own update"
  ],
  "correctionHref": "/guard/security/campaigns/cve-2026-111497-nodejs-brotli-decoder-out-of-bounds-write/corrections"
}
