Improper Input Validation vulnerability in qs (parse modules) allows HTTP DoS.This issue affects qs: < 6.14.1.
SummaryThe arrayLimit option in qs does not enforce limits for bracket notation (a[]=1&a[]=2), allowing attackers to cause denial-of-service via memory exhaustion. Applications using arrayLimit for DoS protection are vulnerable.
DetailsThe arrayLimit option only checks limits for indexed notation (a[0]=1&a[1]=2) but completely bypasses it for bracket notation (a[]=1&a[]=2).
Vulnerable code (lib/parse.js:159-162):
if (root === [] && options.parseArrays) { obj = utils.combine([], leaf); // No arrayLimit check }
Working code (lib/parse.js:175):
else if (index <= options.arrayLimit) { // Limit checked here obj = []; obj[index] = leaf; }
The bracket notation handler at line 159 uses utils.combine([], leaf) without validating against options.arrayLimit, while indexed notation at line 175 checks index <= options.arrayLimit before creating arrays.
PoCTest 1 - Basic bypass:
npm install qs
const qs = require(qs); const result = qs.parse(a[]=1&a[]=2&a[]=3&a[]=4&a[]=5&a[]=6, { arrayLimit: 5 }); console.log(result.a.length); // Output: 6 (should be max 5)
Test 2 - DoS demonstration:
const qs = require(qs); const attack = a[]= + Array(10000).fill(x).join(&a[]=); const result = qs.parse(attack, { arrayLimit: 100 }); console.log(result.a.length); // Output: 10000 (should be max 100)
Configuration:
ImpactDenial of Service via memory exhaustion. Affects applications using qs.parse() with user-controlled input and arrayLimit for protection.
Attack scenario:
Attacker sends HTTP request: GET /api/search?filters[]=x&filters[]=x&…&filters[]=x (100,000+ times)
Application parses with qs.parse(query, { arrayLimit: 100 })
qs ignores limit, parses all 100,000 elements into array
Server memory exhausted → application crashes or becomes unresponsive
Service unavailable for all users Real-world impact:
Single malicious request can crash server
No authentication required
Easy to automate and scale
Affects any endpoint parsing query strings with bracket notation
The product receives input or data, but it does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly.
Input validation is a frequently-used technique for checking potentially dangerous inputs in order to ensure that the inputs are safe for processing within the code, or when communicating with other components. Input can consist of:
Data can be simple or structured. Structured data can be composed of many nested layers, composed of combinations of metadata and raw data, with other simple or structured data. Many properties of raw data or metadata may need to be validated upon entry into the code, such as:
Implied or derived properties of data must often be calculated or inferred by the code itself. Errors in deriving properties may be considered a contributing factor to improper input validation.