Mar 20, 2026·5 min read·3 visits
A structural flaw in Qwik City's form parser allows attackers to overwrite native array methods by mixing numeric and string keys in dotted form paths, leading to unhandled TypeErrors and Denial of Service.
Qwik City middleware versions prior to 1.19.2 contain an array method pollution vulnerability within the form parsing component. Unauthenticated remote attackers can overwrite native array methods via crafted multipart or URL-encoded HTTP requests, resulting in type confusion and server-side Denial of Service (DoS).
Qwik City operates as a meta-framework providing routing and middleware capabilities for Qwik applications. The formToObj function within the request handler is responsible for deserializing incoming form data into structured JavaScript objects. This function processes both URL-encoded and multipart payloads, converting dotted key notations into nested objects or arrays.
Prior to version 1.19.2, this parser lacked rigorous structural validation during object construction. The vulnerability arises from an improper implementation of a one-pass parsing algorithm that fails to enforce type consistency across sibling keys. This oversight allows attackers to inject string properties into instantiated arrays, polluting native array methods.
When the application subsequently attempts to invoke these overwritten methods during form processing, the Node.js runtime throws an unhandled TypeError. This exception terminates the execution context of the active request, resulting in a targeted Denial of Service condition. The flaw exposes applications to unauthenticated remote attacks with low complexity.
The core logical flaw exists in how the legacy parser inferred data types from dotted form keys. When evaluating a key like items.0, the parser examined the numeric segment 0 and initialized the items property as a standard JavaScript Array. This instantiation occurred immediately during the first pass over the form data.
Because the parser processed keys sequentially without validating the full key set, it remained blind to subsequent type contradictions. If the next key in the payload was items.push=polluted, the parser applied the value "polluted" directly to the existing items array. Since arrays in JavaScript are objects, this operation successfully overwrites the native Array.prototype.push method for that specific instance.
The application fails when the parser encounters a subsequent numeric key, such as items.1. The parser recognizes items as an array and attempts to append the new value using the standard push method. Because the attacker previously replaced the push function with a string, the runtime evaluates "polluted"("value"), throwing a fatal type error and crashing the request handler.
Attackers exploit this vulnerability by submitting a maliciously crafted HTTP POST request containing specific form field sequences. The payload must target a route that processes form data using the vulnerable qwik-city middleware. No authentication or specific user roles are required to deliver the payload.
The attack relies on strict ordering of form fields to manipulate the parser state. The first parameter, items.0=first_item, forces the initialization of the array. The second parameter, items.push=polluted, executes the property overwrite. The third parameter, items.1=trigger_crash, triggers the application crash when the parser attempts the insertion.
Beyond the standard push overwrite, attackers can manipulate other native properties. Supplying a payload like items.length=999999999 forces the array length to an artificially high value. If downstream application logic iterates over this array, it induces severe memory allocation overhead or excessive CPU consumption, amplifying the Denial of Service impact.
The remediation, introduced in commit 7b5867c3dd8925df9aa96c4296b1e95a4c2af87d, fundamentally alters the parsing architecture. The maintainers abandoned the one-pass inference model in favor of a robust two-pass evaluation process. The first pass explicitly maps and validates all array paths before any object instantiation occurs.
During the new getArrayPaths pass, the middleware scans the complete set of FormData keys. A parent path is classified as an array exclusively if every single child segment associated with it passes a strict regular expression check. The regex /^(0|[1-9]\d*)$/ enforces canonical, non-negative integer formats, rejecting strings, padded numbers, and scientific notation.
If a path contains any non-numeric sibling keys, the second pass initializes it as a plain object using Object.create(null). This specific instantiation method ensures the resulting object lacks a __proto__ property, immunizing the parser against broader prototype pollution vectors. The strict isolation between verified arrays and prototype-less objects eliminates the type confusion vector entirely.
The primary impact of this vulnerability is a targeted Denial of Service affecting the availability of the application. The unhandled exception occurs synchronously within the request processing pipeline. This causes the specific HTTP request to fail abruptly, typically resulting in a 500 Internal Server Error or a complete connection drop.
While the vulnerability leverages property injection, it does not achieve arbitrary code execution. The injected values are constrained to data properties on the specific array instance within the request context. The attack does not overwrite global prototypes or persist across different user sessions, isolating the crash to the immediate request thread.
The CVSS v3.1 base score of 7.5 accurately reflects the high availability impact combined with the low attack complexity. Attackers can easily automate the generation of these payloads and rapidly deplete server resources or disrupt specific application endpoints by repeatedly triggering the type error.
Organizations utilizing Qwik must update the qwik-city package to version 1.19.2 or later. This release contains the two-pass parser and strict index validation logic required to prevent the method pollution. The update is a drop-in replacement and requires no changes to application-level form handling logic.
If immediate patching is unfeasible, security teams should deploy Web Application Firewall (WAF) rules to inspect incoming form data. The rules must block application/x-www-form-urlencoded and multipart/form-data requests containing dotted keys that end in native array methods. Key targets for blocking include .push, .pop, .shift, .unshift, and .length.
Detection engineering teams can proactively identify exploitation attempts by monitoring application logs for specific stack traces. Alerts should trigger on instances of TypeError: ... is not a function occurring within the formToObj middleware module. Network scanners can also utilize Nuclei templates mimicking the PoC structure to verify exposure across external footprints.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Qwik (qwik-city) QwikDev | < 1.19.2 | 1.19.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-843 |
| Secondary CWE | CWE-1321 |
| Attack Vector | Network |
| CVSS v3.1 Score | 7.5 |
| Impact | Denial of Service |
| EPSS Score | 0.00053 |
| Exploit Status | Proof of Concept |
The application allocates or initializes a resource such as a pointer, object, or variable using one type, but it later accesses that resource using a type that is incompatible with the original type.