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-19481

CVE-2026-19481: Unauthenticated Remote Denial of Service via Prototype Lookup Crash in @fastify/busboy

Amit Schendel
Amit Schendel
Senior Security Researcher

Oct 3, 2026·7 min read·14 visits

Executive Summary (TL;DR)

Unauthenticated remote attackers can crash Node.js servers using @fastify/busboy by sending a multipart request with __proto__ or constructor in the headers, triggering an unhandled TypeError.

A critical remote, unauthenticated Denial of Service (DoS) vulnerability in @fastify/busboy (<= 3.2.0) allows attackers to crash the Node.js process. By submitting a crafted multipart/form-data request with a header key matching an inherited property of Object.prototype (like __proto__ or constructor), the internal HeaderParser triggers a synchronous TypeError.

Vulnerability Overview and Attack Surface

The vulnerability CVE-2026-19481 describes a remote, unauthenticated Denial of Service (DoS) flaw within the @fastify/busboy multipart form-data parser for Node.js. This library serves as a critical infrastructure component, parsing streaming incoming data in numerous web applications and frameworks, including Fastify. The attack surface is exposed via any endpoint accepting HTTP POST or PUT requests formatted as multipart/form-data payloads.\n\nAt its core, the vulnerability resides in the integrated dicer component located at deps/dicer/lib/HeaderParser.js. This module parses the headers of incoming multipart boundaries sequentially. Because the parser utilizes standard plain JavaScript objects ({}) to temporarily store parsed headers, it remains susceptible to prototype property collision attacks.\n\nWhen a request contains a part header with a name that overlaps with built-in properties of Object.prototype, such as __proto__ or constructor, the internal dictionary lookup fails to distinguish between 'own properties' and inherited properties. This behavior leads to type confusion within the parser's logic. If an application does not catch the resulting synchronous error, the Node.js event loop terminates, resulting in a complete Denial of Service.

Root Cause Analysis of Prototype Lookup Collision

JavaScript objects instantiated via the literal notation {} inherit properties and methods directly from the global Object.prototype. These inherited properties include standard utility methods and internal pointers such as toString, valueOf, constructor, and __proto__. When an application performs a property lookup on a plain object, the JavaScript engine searches the object's own keys first, subsequently traversing the prototype chain if the key is not found.\n\nIn the vulnerable versions of @fastify/busboy (versions 1.0.0 through 3.2.0), the HeaderParser class processes multipart headers and aggregates duplicates into an array. It initializes its internal header storage dictionary using this.header = {}. When parsing each header line, the parser extracts the header name, converts it to lowercase, and performs a lookup operation: this.header[h] || (this.header[h] = []).\n\nIf the lowercase header key matches a property belonging to Object.prototype (for example, __proto__), the lookup expression evaluates to the built-in prototype object. The logical OR operator (||) short-circuits because Object.prototype is a truthy value, bypassing the array initialization branch. Consequently, the variable storing the header accumulation structure is assigned Object.prototype rather than a new empty array.\n\nImmediately following this lookup, the parser invokes the .push() method on the returned reference: values.push(...). Because Object.prototype does not implement a push method, the engine throws a synchronous TypeError. This uncaught exception propagates up the execution stack, aborting the asynchronous parsing thread and terminating the parent process.

Vulnerable Code and Patch Walkthrough

To understand the structural failure, we analyze the vulnerable logic in deps/dicer/lib/HeaderParser.js. The initialization logic establishes a plain object cache, while the header parsing loop attempts to write incoming headers directly into this object without checking ownership:\n\njavascript\n// Vulnerable constructor initialization\nfunction HeaderParser (cfg) {\n // ...\n this.buffer = ''\n this.header = {} // Vulnerable plain object initialization\n this.finished = false\n this.tail = ''\n}\n\n// Vulnerable parser accumulator logic\nHeaderParser.prototype._parseHeader = function () {\n // ...\n h = buffer.slice(lineStart, posColon).toLowerCase()\n let valueStart = posColon + 1\n if (buffer[valueStart] === ' ' || buffer[valueStart] === '\\t') { ++valueStart }\n \n // If h is '__proto__', this.header[h] resolves to Object.prototype\n const values = this.header[h] || (this.header[h] = [])\n // This throws 'TypeError: values.push is not a function'\n values.push(buffer.slice(valueStart, lineEnd))\n // ...\n}\n\n\nThe official security patch (957a24b66d5915e6d0a6ac988c9dbcee86373e9b) resolves the vulnerability by implementing prototype-less objects via Object.create(null). These objects do not possess a link to Object.prototype and therefore contain zero inherited properties. The modified logic ensures that looking up __proto__ or constructor yields undefined, forcing the code to safely initialize a new array directly on the object as an 'own' property.\n\ndiff\n@@ -17,7 +17,7 @@ function HeaderParser (cfg) {\n this.maxHeaderPairs = getLimit(cfg, 'maxHeaderPairs', 2000)\n this.maxHeaderSize = getLimit(cfg, 'maxHeaderSize', 80 * 1024)\n this.buffer = ''\n- this.header = {}\n+ this.header = Object.create(null)\n this.finished = false\n this.tail = ''\n }\n@@ -82,14 +82,14 @@ HeaderParser.prototype.push = function (data) {\n HeaderParser.prototype.reset = function () {\n this.finished = false\n this.buffer = ''\n- this.header = {}\n+ this.header = Object.create(null)\n this.tail = ''\n }\n \n HeaderParser.prototype._finish = function () {\n if (this.buffer) { this._parseHeader() }\n const header = this.header\n- this.header = {}\n+ this.header = Object.create(null)\n this.buffer = ''\n this.tail = ''\n this.finished = true\n\n\nThis fix is complete and robust because it prevents the lookup from resolving to any prototype method, ensuring that any user-controlled header keys are treated strictly as isolated data attributes.

Exploitation and Attack Flow

Exploitation of CVE-2026-19481 requires no authentication or specific configuration. An attacker merely needs to deliver a structured multipart form-data payload containing an HTTP part header named __proto__ or constructor to an endpoint that utilizes the vulnerable library. The parsing engine processes the payload sequentially as it streams from the socket.\n\nThe following sequence diagram illustrates the transaction flow that triggers the crash:\n\nmermaid\ngraph LR\n Attacker[\"Attacker\"] -->|\"1. HTTP POST with __proto__ header\"| WebServer[\"Web Server (Node.js)\"]\n WebServer -->|\"2. Stream request chunks\"| Busboy[\"@fastify/busboy Parser\"]\n Busboy -->|\"3. Extract header name '__proto__'\"| HeaderParser[\"HeaderParser\"]\n HeaderParser -->|\"4. Lookup: this.header['__proto__']\"| Prototype[\"Object.prototype\"]\n HeaderParser -->|\"5. Call: values.push() on Object.prototype\"| Crash[\"TypeError & Process Crash\"]\n\n\nAn attacker can trigger this state using command-line tools such as curl. Because Node.js operates on a single-threaded event loop by default, a synchronous uncaught exception thrown in the main context terminates the entire process immediately. Any active connections are severed, and the service remains unavailable until an external process manager (such as pm2 or systemd) restarts the container or application server.

Impact and Severity Assessment

The Common Vulnerability Scoring System (CVSS) v3.1 rates this vulnerability at a base score of 7.5 (High), reflecting a high availability impact with low complexity and no privileges required. The specific vector is CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H. The primary consequence of this vulnerability is systemic Denial of Service (DoS).\n\nBecause @fastify/busboy is often integrated as a low-level parsing utility inside core middleware stacks, a single malicious payload can affect all active users sharing the target process instance. Under rapid attack execution, an attacker can continuously crash newly spawned processes, completely exhausting system resources and causing persistent downtime.\n\nWhile there is no confidentiality or integrity impact (since the vulnerability does not leak memory or permit arbitrary file system access), the disruption to service availability is severe. The EPSS score is 0.00493, representing a low-to-moderate short-term threat, but the trivial nature of the exploit means that public disclosure introduces immediate exploitation risks for unpatched legacy installations.

Remediation and Mitigation Strategies

The primary and recommended resolution is to upgrade @fastify/busboy to version 3.2.1 or later. This release enforces prototype-less object dictionaries throughout the lifecycle of the parser. Organizations using yarn, npm, or pnpm should audit their dependency trees to ensure transitive installations of @fastify/busboy are updated.\n\nIf upgrading immediately is not feasible, temporary mitigation can be applied at the edge of the network. Web Application Firewalls (WAFs) or reverse proxies (such as NGINX or Cloudflare) can be configured to inspect incoming multipart/form-data request bodies. Any request containing header keys such as __proto__: or constructor: within the boundary sections should be rejected with an HTTP 400 Bad Request error.\n\nAdditionally, developers should avoid copying or merging parsed header objects into standard plain objects downstream. Cloning the parsed header collection using spread operators (e.g., { ...headers }) or Object.assign({}, headers) will re-attach the global Object.prototype, potentially introducing secondary prototype lookup or pollution risks within subsequent application logic.

Official Patches

FastifyFix commit implementing Object.create(null) for HeaderParser cache
FastifyRelease v3.2.1 containing the security patch

Fix Analysis (1)

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
EPSS Probability
0.49%
Top 60% most exploited

Affected Systems

Node.js applications running @fastify/busboy versions >= 1.0.0 and <= 3.2.0Web frameworks utilizing affected versions of @fastify/busboy as a multipart parsing engine (e.g., Fastify, NestJS configurations)

Affected Versions Detail

Product
Affected Versions
Fixed Version
@fastify/busboy
Fastify
>= 1.0.0, <= 3.2.03.2.1
AttributeDetail
CWE IDCWE-754 (Variant of CWE-1321 Prototype Pollution via Prototype Lookup Crash)
Attack VectorNetwork (AV:N)
Attack ComplexityLow (AC:L)
Privileges RequiredNone (PR:N)
User InteractionNone (UI:N)
CVSS v3.1 Score7.5 (High)
Exploit StatusProof-of-Concept (PoC) in Test Suite
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-754
Improper Check for Unusual or Exceptional Conditions

The software does not check or incorrectly checks for unusual or exceptional conditions, leading to unexpected behavior or resource exhaustion.

Known Exploits & Detection

Official Test Suite & AdvisoryOfficial proof-of-concept tests demonstrating process termination upon receipt of prototype-inherited header keys in the multipart payload

Vulnerability Timeline

Official Security Patch implemented by Matteo Collina in @fastify/busboy repository.
2026-08-12
Advisory Published under ID GHSA-x8mw-p69m-v3mx on GitHub; CVE-2026-19481 formally assigned.
2026-08-13
Fixed version 3.2.1 released to the public on the npm registry.
2026-08-13

References & Sources

  • [1]https://nvd.nist.gov/vuln/detail/CVE-2026-19481
  • [2]https://github.com/fastify/busboy/security/advisories/GHSA-x8mw-p69m-v3mx
  • [3]https://cna.openjsf.org/security-advisories.html
  • [4]https://github.com/fastify/busboy/commit/957a24b66d5915e6d0a6ac988c9dbcee86373e9b
  • [5]https://github.com/fastify/busboy/releases/tag/v3.2.1

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

•1 day ago•CVE-2026-107844
5.3

CVE-2026-107844: Path Traversal Vulnerability in Contao ImagesController

A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.

Amit Schendel
Amit Schendel
8 views•5 min read
•1 day ago•CVE-2026-107848
3.5

CVE-2026-107848: Cross-Site Request Forgery (CSRF) in Contao Backend Actions via GET Requests

Contao Open Source CMS versions 4.0.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 contain a Cross-Site Request Forgery (CSRF) vulnerability in backend parameter handling. The `RequestTokenListener` component validates anti-CSRF tokens solely for HTTP POST requests, while GET-based declarative guards run only when an `act` parameter is present in the query string. Consequently, custom backend actions dispatched via alternative parameters such as `key=` can execute without CSRF token verification when triggered by an authenticated user.

Amit Schendel
Amit Schendel
7 views•5 min read
•1 day ago•CVE-2026-107843
5.3

CVE-2026-107843: Unthrottled Activation Email Resend and Account Enumeration in Contao CMS

Contao CMS versions 4.1.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 fail to validate form submission tokens and enforce rate limiting when processing activation email resend requests via HTTP POST, enabling resource exhaustion and account state enumeration.

Amit Schendel
Amit Schendel
8 views•4 min read
•1 day ago•CVE-2026-107842
5.3

CVE-2026-107842: Information Disclosure via Stale Indexing in Contao Search Module

An information disclosure vulnerability in Contao CMS allows unauthenticated site visitors to view protected page titles, URLs, and text excerpts through search queries when protected page indexing is disabled after previously being enabled.

Amit Schendel
Amit Schendel
10 views•4 min read
•1 day ago•GHSA-G38J-7V97-X298
6.5

GHSA-G38J-7V97-X298: Missing Authorization Check in Vikunja CalDAV Task Relation Creation

In Vikunja prior to version 2.6.0, relation creation via the CalDAV endpoint fails to invoke the TaskRelation.CanCreate authorization check. This missing access control allows an authenticated user to establish unauthorized relationships and perform write operations against any task, provided its unique identifier (UID) is known.

Alon Barad
Alon Barad
12 views•5 min read
•1 day ago•GHSA-3HC7-R24J-RPWC
6.8

GHSA-3hc7-r24j-rpwc: Cross-Project Task Disclosure via Subtask Expansion in Vikunja

A cross-project information disclosure vulnerability in Vikunja allows authenticated users with read access to one project to view private task details from unauthorized projects via subtask expansion parameters.

Alon Barad
Alon Barad
9 views•5 min read