Sep 1, 2026·6 min read·0 visits
The decode-uri-component package (versions 0.1.0 to 0.4.1) contains an algorithmic complexity vulnerability that enables unauthenticated remote attackers to block the single-threaded Node.js event loop and cause a complete Denial of Service via crafted malformed URI payloads.
A critical algorithmic complexity Denial of Service (DoS) vulnerability exists in the npm package decode-uri-component versions 0.1.0 through 0.4.1. The package employs an inefficient, high-complexity recursive mechanism when processing invalid percent-encoded sequences, such as isolated continuation bytes. An attacker can exploit this behavior by sending malformed strings, causing the Node.js event loop to block entirely and exhausting CPU resources. This vulnerability is resolved in version 0.5.0 by replacing the recursive parser with a single-pass, linear scanning algorithm.
The decode-uri-component package is designed to safely parse and decode percent-encoded UTF-8 strings. It functions as a resilient utility, catching errors that native JavaScript decoders throw and attempting to output readable characters for invalid sequences. This fallback strategy introduces a substantial attack surface when handling unvalidated input from remote sources.\n\nThe vulnerability, registered as CVE-2026-45822, is classified under CWE-400 (Uncontrolled Resource Consumption) and CWE-407 (Inefficient Algorithmic Complexity). It manifests when the custom decoding fallback loop receives input structured to fail native decoding. Instead of running in linear time, the custom fallback router executes an inefficient recursive scheme.\n\nBecause Node.js operates on a single-threaded architecture, any blocking execution path halts the entire event loop. When a web server processes query parameters, header fields, or routing paths using a vulnerable version of this library, a single malicious payload can tie up the CPU thread indefinitely. This behavior allows remote, unauthenticated attackers to systematically exhaust server capacity.
The underlying flaw is located within the custom decoding logic of the index.js file. When the native decodeURIComponent() function encounters invalid sequences, such as isolated UTF-8 continuation bytes, it throws a URIError. The library catches this exception and redirects the parsing path to the custom fallback decode() subroutine.\n\nIn the pre-patched codebase, the input is first divided into tokens via a regular expression matcher. This separates percent-encoded bytes and literal characters into distinct elements in an array. The implementation then iterates through this token array using an outer loop that executes $N - 1$ times, where $N$ is the total token count. Within this loop, the library calls the recursive helper decodeComponents(tokens, i) with a dynamic split point.\n\nInside decodeComponents, if the overall native decoding attempt fails, the token array splits into left and right sub-arrays. However, during the subsequent recursive calls, no split parameter is supplied to the function. This omission causes the split value to default to one, forcing the recursion to process the array by peeling off exactly one token at a time. The combination of the outer loop running $N$ times and the recursive peeling taking $O(N^2)$ string allocations results in a total algorithmic complexity of $O(N^3)$, causing polynomial CPU scaling.
A close examination of the pre-patched and patched source code highlights how the recursive structure was replaced. The vulnerable implementation relies on array partitioning and repeated concatenation of divided tokens. This structure causes exponential allocation and evaluation steps for invalid sequence segments.\n\njavascript\n// Vulnerable custom fallback execution path\nfunction decodeComponents(components, split) {\n\ttry {\n\t\treturn [decodeURIComponent(components.join(''))];\n\t} catch {\n\t\t// Do nothing\n\t}\n\tif (components.length === 1) {\n\t\treturn components;\n\t}\n\tsplit = split || 1;\n\tconst left = components.slice(0, split);\n\tconst right = components.slice(split);\n\treturn Array.prototype.concat.call([], decodeComponents(left), decodeComponents(right));\n}\n\n\nThe patched implementation in version 0.5.0 completely eliminates decodeComponents and replaces it with a linear, single-pass scanner. It evaluates percent-encoded sequences sequentially from left to right. This state-machine approach ensures that invalid segments are ignored or printed literally in a single execution step without triggering backtracking or recursion.\n\njavascript\n// Patched linear custom fallback scanner\nfunction decode(input) {\n\ttry {\n\t\treturn decodeURIComponent(input);\n\t} catch {\n\t\tlet output = '';\n\t\tlet position = 0;\n\t\twhile (position < input.length) {\n\t\t\t// Linear iteration checks lead byte structure and skips backtracking\n\t\t\tconst firstByte = parsePercentByte(input, position);\n\t\t\t// ... [structural validation steps in O(n) complexity]\n\t\t}\n\t\treturn output;\n\t}\n}\n\n\nThis remediation path is complete and robust. By substituting the recursive array processing mechanism with a direct linear scanner, the library guarantees deterministic execution times even when processing highly malformed structures. There are no remaining paths in the codebase that can trigger secondary super-linear resource exhaustion.
Exploitation of CVE-2026-45822 requires no authentication, privilege, or special environment configuration. An attacker merely needs to transmit an HTTP request containing a string of invalid percent-encoded sequences to any component that parses input using the vulnerable library. Common targets include query string parsers, path parameter deserializers, and incoming header processors.\n\nThe payload must be constructed from repeating lone UTF-8 continuation bytes, such as %ab. Because these bytes do not form structurally complete UTF-8 sequences, they force the native parser to error out, routing the input directly into the vulnerable fallback code path. The longer the sequence of invalid tokens, the longer the main thread remains blocked.\n\nmermaid\ngraph LR\n A["Malicious HTTP Request"] --> B["decodeURIComponent(input)"]\n B -- "Throws URIError" --> C["Fallback decode() Method"]\n C --> D["Recursive Splitting Loop"]\n D --> E["Cubic O(N^3) Execution"]\n E --> F["Event Loop Blocked & 100% CPU Usage"]\n\n\nThe relationship between token length and processing time shows a sharp cubic curve. A payload containing 200 tokens blocks the CPU for less than a second, while a payload of 1400 tokens freezes the event loop for approximately 33 seconds. This freeze prevents the server from answering other legitimate incoming requests, leading to a complete service outage.
The impact of this vulnerability is severe for Node.js production environments. Because Node.js utilizes a single-threaded event loop, any synchronous code that consumes intensive CPU cycles will prevent the thread from processing other asynchronous events. This means a single concurrent request can effectively take down an entire container or server instance.\n\nWhile the CVSS v4.0 score is rated as 6.6, the threat in microservice architectures is disproportionately high. If an API gateway or ingress controller relies on a vulnerable version of decode-uri-component to parse query parameters, an attacker can disable the entire entry point of an enterprise network. This can be accomplished with negligible outbound traffic and minimal attacker bandwidth.\n\nAccording to current EPSS data, the probability of immediate exploitation is estimated at 0.00507 (41.20th percentile). However, due to the widespread distribution of this package as a transit dependency across the npm package registry, the actual corporate exposure rate remains high. Teams should prioritize remediation even if their direct application code does not import the library.
Remediation of CVE-2026-45822 requires upgrading the package to version 0.5.0 or above. Because this vulnerability is often introduced through third-party dependencies, developers must review and update lockfiles. Standard package manager update commands can resolve these nested dependencies automatically.\n\nTo identify vulnerable instances in your codebase, execute the dependency analyzer command npm ls decode-uri-component. If vulnerable versions (0.1.0 through 0.4.1) are detected, you can apply overrides in your project configuration. This forces package managers to resolve all instances to the secure version.\n\njson\n{\n "overrides": {\n "decode-uri-component": "^0.5.0"\n }\n}\n\n\nFor yarn-based environments, you should implement resolutions in the package.json file. This ensures that even indirect, nested dependencies are directed to use the safe version without breaking compatibility. Running security scans via npm audit inside continuous integration pipelines will help prevent the reintroduction of the vulnerable library.
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:U/S:N/AU:Y/R:U/V:D/RE:M/U:Amber| Product | Affected Versions | Fixed Version |
|---|---|---|
decode-uri-component Sam Verschueren | >= 0.1.0, <= 0.4.1 | 0.5.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-407 (Inefficient Algorithmic Complexity) |
| Attack Vector | Network (Remote, Unauthenticated) |
| CVSS v4.0 Score | 6.6 |
| EPSS Score | 0.00507 (41.20th percentile) |
| Impact | Denial of Service (Node.js Event Loop Freeze) |
| Exploit Status | Proof-of-Concept Available |
| KEV Status | Not Listed |
The algorithm used has an inefficient complexity (super-linear), which allows attackers to exhaust system resources with small input sizes.
An in-depth analysis of CVE-2026-81889, a critical Server-Side Request Forgery (SSRF) vulnerability in the remote URL upload component of elFinder web file manager before version 2.1.70. The flaw leverages DNS rebinding due to insecure socket fallbacks when the PHP cURL extension is missing, resulting in access to internal network resources and local loopback services.
A critical path traversal vulnerability was discovered in the Kirby CMS media component. Prior to versions 4.9.5 and 5.5.2, Kirby failed to validate path-traversal indicators in requested filenames, allowing attackers to check for the existence of local JSON files, delete them, or bypass directory prefix containment logic under certain web server configurations.
A missing authorization vulnerability (CWE-862) in Kirby CMS (versions 5.0.0 through 5.5.1) allows low-privileged authenticated users with Panel access to write temporary chunk files to disk, leading to potential Denial of Service via storage exhaustion.
An input validation vulnerability in the WebTransport upgrade handler of the Engine.IO server (the core engine driving Socket.IO) allows remote, unauthenticated attackers to trigger a denial of service via application crashes. By sending a crafted session identifier corresponding to a JavaScript prototype property (such as __proto__), an attacker forces the server to reference Object.prototype instead of a valid socket instance, causing a fatal TypeError in the asynchronous execution context.
An authentication bypass vulnerability in @hono/oauth-providers prior to version 0.8.6 allows unauthenticated remote attackers to perform login Cross-Site Request Forgery (CSRF) and forced account linking. Due to a logical 'fail-open' comparison flaw, the middleware validates OAuth callbacks when the state parameter is omitted from both the client cookie and the request query parameters, completely bypassing standard anti-CSRF protections.
CVE-2026-15305 describes a critical security vulnerability within the TYPO3 CMS Form Framework (ext:form) extension. Due to a lifecycle timing mismatch, server-side MIME type validation was bypassed when processing files uploaded via FileUpload or ImageUpload form elements. This allowed remote, unauthenticated attackers to upload arbitrary file types (with the exception of blocked PHP extensions) to the web server's public storage directory.