Every CVE Search/ Get API key

CVE-2026-82562

qs.parse does not enforce arrayLimit on comma groups under bracket-push keys when throwOnLimitExceeded is set (incomplete fix for CVE-2026-2391)

6.3 MediumFix available

Summary

When qs.parse is called with comma: true and throwOnLimitExceeded: true, a comma-separated value under a bracket-push key (a[]=1,2,3,4) is split into an array without being compared against arrayLimit, while the same value under a flat key (a=1,2,3,4), an indexed key (a[0]=), a nested key (a[b]=), or a dotted key (a.b= with allowDots) throws the documented RangeError. A single parameter such as a[]=1,2,2,... therefore produces an inner array of arbitrary length even though the caller opted into the hard limit. This is the []= key form that the fix for CVE-2026-2391 (qs 6.14.2) did not cover.

Details

In lib/parse.js, a comma-separated value under a []= key is split and then wrapped as a single nested element (val = [val], so that each a[]=x,y group counts as one element of the outer array). The arrayLimit check that 6.14.2 added for comma values runs after that wrap, so for []= parts it only ever saw the wrapper of length 1. 6.15.3 added a pre-split comma count so that an oversized value throws before it is allocated, but gated it on an isFlatArrayValue flag that parseValues set to false for any part containing []=, and did not pass it for object-valued input, so the gap remained.

PoC




var qs = require('qs');



var options = { comma: true, arrayLimit: 3, throwOnLimitExceeded: true };



qs.parse('a=1,2,3,4', options);   // RangeError: Array limit exceeded. Only 3 elements allowed in an array.



qs.parse('a[]=1,2,3,4', options); // { a: [ [ '1', '2', '3', '4' ] ] }  (no throw)



qs.parse('a[]=' + '1,'.repeat(1000000) + '1', { comma: true, arrayLimit: 20, throwOnLimitExceeded: true });



// no throw; a 1,000,001-element inner array is allocated



Fix

lib/parse.js, applied in 8859c37 on main and released as v6.16.0: the isFlatArrayValue gate is removed, so every comma-split value is counted against arrayLimit before splitting regardless of key form. An in-limit group under a[]= still counts as one element of the outer array, and the default (throwOnLimitExceeded: false) path is unchanged.

Affected versions

>=6.14.2 <6.16.0, fixed in v6.16.0.

v6.14.2 introduced arrayLimit enforcement for comma values (the fix for CVE-2026-2391) but only for values not under a []= key, and every release from v6.14.2 through v6.15.3 has the same gap. v6.14.0 and v6.14.1, where throwOnLimitExceeded exists but does not apply to any comma form, are covered by CVE-2026-2391 rather than this record. Earlier lines (6.7.x through 6.13.x) have comma but no throwOnLimitExceeded, so there is no hard cap on any comma path to bypass; releases before 6.7.0 have no comma option.

Impact

An unauthenticated attacker who can reach an application that parses untrusted query strings or urlencoded bodies with both comma: true and throwOnLimitExceeded: true (both non-default) can bypass the configured limit with a single a[]= parameter and force the parser to allocate an array proportional to the request size. The cost is strictly linear in the attacker-supplied bytes (about 0.1 microseconds and 6 to 7 retained bytes per input byte; the same out-of-memory threshold as the documented default throwOnLimitExceeded: false path), so a transport-layer request or body size limit bounds it completely (and node's default maximum HTTP header size of 16 KB already bounds the request line, so multi-megabyte payloads need a body parser). The impact is that an opt-in hard limit fails open on one key spelling, not unbounded allocation from a small input.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
None
Availability
Low

Exploit likelihood

0.54%Up 0.2 points since Aug 30, 2026
90%50%10%1%

What each source reports

CVE List Score used 6.3

qs.parse does not enforce arrayLimit on comma groups under bracket-push keys when throwOnLimitExceeded is set (incomplete fix for CVE-2026-2391)

Summary

When qs.parse is called with comma: true and throwOnLimitExceeded: true, a comma-separated value under a bracket-push key (a[]=1,2,3,4) is split into an array without being compared against arrayLimit, while the same value under a flat key (a=1,2,3,4), an indexed key (a[0]=), a nested key (a[b]=), or a dotted key (a.b= with allowDots) throws the documented RangeError. A single parameter such as a[]=1,2,2,... therefore produces an inner array of arbitrary length even though the caller opted into the hard limit. This is the []= key form that the fix for CVE-2026-2391 (qs 6.14.2) did not cover.

Details

In lib/parse.js, a comma-separated value under a []= key is split and then wrapped as a single nested element (val = [val], so that each a[]=x,y group counts as one element of the outer array). The arrayLimit check that 6.14.2 added for comma values runs after that wrap, so for []= parts it only ever saw the wrapper of length 1. 6.15.3 added a pre-split comma count so that an oversized value throws before it is allocated, but gated it on an isFlatArrayValue flag that parseValues set to false for any part containing []=, and did not pass it for object-valued input, so the gap remained.

PoC




var qs = require('qs');



var options = { comma: true, arrayLimit: 3, throwOnLimitExceeded: true };



qs.parse('a=1,2,3,4', options);   // RangeError: Array limit exceeded. Only 3 elements allowed in an array.



qs.parse('a[]=1,2,3,4', options); // { a: [ [ '1', '2', '3', '4' ] ] }  (no throw)



qs.parse('a[]=' + '1,'.repeat(1000000) + '1', { comma: true, arrayLimit: 20, throwOnLimitExceeded: true });



// no throw; a 1,000,001-element inner array is allocated



Fix

lib/parse.js, applied in 8859c37 on main and released as v6.16.0: the isFlatArrayValue gate is removed, so every comma-split value is counted against arrayLimit before splitting regardless of key form. An in-limit group under a[]= still counts as one element of the outer array, and the default (throwOnLimitExceeded: false) path is unchanged.

Affected versions

>=6.14.2 <6.16.0, fixed in v6.16.0.

v6.14.2 introduced arrayLimit enforcement for comma values (the fix for CVE-2026-2391) but only for values not under a []= key, and every release from v6.14.2 through v6.15.3 has the same gap. v6.14.0 and v6.14.1, where throwOnLimitExceeded exists but does not apply to any comma form, are covered by CVE-2026-2391 rather than this record. Earlier lines (6.7.x through 6.13.x) have comma but no throwOnLimitExceeded, so there is no hard cap on any comma path to bypass; releases before 6.7.0 have no comma option.

Impact

An unauthenticated attacker who can reach an application that parses untrusted query strings or urlencoded bodies with both comma: true and throwOnLimitExceeded: true (both non-default) can bypass the configured limit with a single a[]= parameter and force the parser to allocate an array proportional to the request size. The cost is strictly linear in the attacker-supplied bytes (about 0.1 microseconds and 6 to 7 retained bytes per input byte; the same out-of-memory threshold as the documented default throwOnLimitExceeded: false path), so a transport-layer request or body size limit bounds it completely (and node's default maximum HTTP header size of 16 KB already bounds the request line, so multi-megabyte payloads need a body parser). The impact is that an opt-in hard limit fails open on one key spelling, not unbounded allocation from a small input.

Record
CVE-2026-82562
CVSS 4.0
6.3 MediumCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N
CVSS 3.1
3.7 LowCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
Weakness
CWE-770
Updated
2026-11-02
EUVDEUVD-2026-68141 6.3

Summary

When qs.parse is called with comma: true and throwOnLimitExceeded: true, a comma-separated value under a bracket-push key (a[]=1,2,3,4) is split into an array without being compared against arrayLimit, while the same value under a flat key (a=1,2,3,4), an indexed key (a[0]=), a nested key (a[b]=), or a dotted key (a.b= with allowDots) throws the documented RangeError. A single parameter such as a[]=1,2,2,... therefore produces an inner array of arbitrary length even though the caller opted into the hard limit. This is the []= key form that the fix for CVE-2026-2391 (qs 6.14.2) did not cover.

Details

In lib/parse.js, a comma-separated value under a []= key is split and then wrapped as a single nested element (val = [val], so that each a[]=x,y group counts as one element of the outer array). The arrayLimit check that 6.14.2 added for comma values runs after that wrap, so for []= parts it only ever saw the wrapper of length 1. 6.15.3 added a pre-split comma count so that an oversized value throws before it is allocated, but gated it on an isFlatArrayValue flag that parseValues set to false for any part containing []=, and did not pass it for object-valued input, so the gap remained.

PoC




var qs = require('qs');



var options = { comma: true, arrayLimit: 3, throwOnLimitExceeded: true };



qs.parse('a=1,2,3,4', options);   // RangeError: Array limit exceeded. Only 3 elements allowed in an array.



qs.parse('a[]=1,2,3,4', options); // { a: [ [ '1', '2', '3', '4' ] ] }  (no throw)



qs.parse('a[]=' + '1,'.repeat(1000000) + '1', { comma: true, arrayLimit: 20, throwOnLimitExceeded: true });



// no throw; a 1,000,001-element inner array is allocated



Fix

lib/parse.js, applied in 8859c37 on main and released as v6.16.0: the isFlatArrayValue gate is removed, so every comma-split value is counted against arrayLimit before splitting regardless of key form. An in-limit group under a[]= still counts as one element of the outer array, and the default (throwOnLimitExceeded: false) path is unchanged.

Affected versions

>=6.14.2 <6.16.0, fixed in v6.16.0.

v6.14.2 introduced arrayLimit enforcement for comma values (the fix for CVE-2026-2391) but only for values not under a []= key, and every release from v6.14.2 through v6.15.3 has the same gap. v6.14.0 and v6.14.1, where throwOnLimitExceeded exists but does not apply to any comma form, are covered by CVE-2026-2391 rather than this record. Earlier lines (6.7.x through 6.13.x) have comma but no throwOnLimitExceeded, so there is no hard cap on any comma path to bypass; releases before 6.7.0 have no comma option.

Impact

An unauthenticated attacker who can reach an application that parses untrusted query strings or urlencoded bodies with both comma: true and throwOnLimitExceeded: true (both non-default) can bypass the configured limit with a single a[]= parameter and force the parser to allocate an array proportional to the request size. The cost is strictly linear in the attacker-supplied bytes (about 0.1 microseconds and 6 to 7 retained bytes per input byte; the same out-of-memory threshold as the documented default throwOnLimitExceeded: false path), so a transport-layer request or body size limit bounds it completely (and node's default maximum HTTP header size of 16 KB already bounds the request line, so multi-megabyte payloads need a body parser). The impact is that an opt-in hard limit fails open on one key spelling, not unbounded allocation from a small input.

Record
EUVD-2026-68141
CVSS 4.0
6.3 MediumCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-x5fp-wj9c-mxmx 6.3

qs array-limit bypass via bracket-key comma parsing

Summary

qs v6.15.3 allows bracket-key input to bypass arrayLimit and throwOnLimitExceeded when comma: true. The input a[]=1,2,3,4 succeeds with arrayLimit: 3, while the equivalent plain-key input is rejected.

Affected version tested:

qs v6.15.3
commit 18d085e919dae70c8f1b200ab99323058edab2c2

Details

parseArrayValue() enforces the comma limit only for flat values. The a[] form is marked non-flat, so its comma-separated value is wrapped after parsing and the inner array is not checked. A single parameter can therefore materialize arbitrarily large arrays.

PoC

const qs = require('qs')
const options = { comma: true, arrayLimit: 3, throwOnLimitExceeded: true }

const result = qs.parse('a[]=1,2,3,4', options)
console.log(result.a[0].length) // 4; expected RangeError

const big = qs.parse('a[]=' + '1,'.repeat(1000000) + '1', { comma: true, arrayLimit: 20 })
console.log(big.a[0].length) // 1000001

On v6.15.3, the first input parses successfully and the second creates an array with 1,000,001 elements. The equivalent a=1,2,3,4 input throws RangeError as expected.

Impact

An attacker who can supply a query string or form body can bypass configured array limits and force excessive memory allocation, causing denial of service. The limit must be applied after comma splitting and before the resulting array is wrapped.

Record
GHSA-x5fp-wj9c-mxmx
CVSS 4.0
6.3 MediumCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N
CVSS 3.1
3.7 LowCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
Weakness
CWE-770
Updated
2026-11-02
NVD 6.3

Summary

When qs.parse is called with comma: true and throwOnLimitExceeded: true, a comma-separated value under a bracket-push key (a[]=1,2,3,4) is split into an array without being compared against arrayLimit, while the same value under a flat key (a=1,2,3,4), an indexed key (a[0]=), a nested key (a[b]=), or a dotted key (a.b= with allowDots) throws the documented RangeError. A single parameter such as a[]=1,2,2,... therefore produces an inner array of arbitrary length even though the caller opted into the hard limit. This is the []= key form that the fix for CVE-2026-2391 (qs 6.14.2) did not cover.

Details

In lib/parse.js, a comma-separated value under a []= key is split and then wrapped as a single nested element (val = [val], so that each a[]=x,y group counts as one element of the outer array). The arrayLimit check that 6.14.2 added for comma values runs after that wrap, so for []= parts it only ever saw the wrapper of length 1. 6.15.3 added a pre-split comma count so that an oversized value throws before it is allocated, but gated it on an isFlatArrayValue flag that parseValues set to false for any part containing []=, and did not pass it for object-valued input, so the gap remained.

PoC




var qs = require('qs');



var options = { comma: true, arrayLimit: 3, throwOnLimitExceeded: true };



qs.parse('a=1,2,3,4', options);   // RangeError: Array limit exceeded. Only 3 elements allowed in an array.



qs.parse('a[]=1,2,3,4', options); // { a: [ [ '1', '2', '3', '4' ] ] }  (no throw)



qs.parse('a[]=' + '1,'.repeat(1000000) + '1', { comma: true, arrayLimit: 20, throwOnLimitExceeded: true });



// no throw; a 1,000,001-element inner array is allocated



Fix

lib/parse.js, applied in 8859c37 on main and released as v6.16.0: the isFlatArrayValue gate is removed, so every comma-split value is counted against arrayLimit before splitting regardless of key form. An in-limit group under a[]= still counts as one element of the outer array, and the default (throwOnLimitExceeded: false) path is unchanged.

Affected versions

>=6.14.2 <6.16.0, fixed in v6.16.0.

v6.14.2 introduced arrayLimit enforcement for comma values (the fix for CVE-2026-2391) but only for values not under a []= key, and every release from v6.14.2 through v6.15.3 has the same gap. v6.14.0 and v6.14.1, where throwOnLimitExceeded exists but does not apply to any comma form, are covered by CVE-2026-2391 rather than this record. Earlier lines (6.7.x through 6.13.x) have comma but no throwOnLimitExceeded, so there is no hard cap on any comma path to bypass; releases before 6.7.0 have no comma option.

Impact

An unauthenticated attacker who can reach an application that parses untrusted query strings or urlencoded bodies with both comma: true and throwOnLimitExceeded: true (both non-default) can bypass the configured limit with a single a[]= parameter and force the parser to allocate an array proportional to the request size. The cost is strictly linear in the attacker-supplied bytes (about 0.1 microseconds and 6 to 7 retained bytes per input byte; the same out-of-memory threshold as the documented default throwOnLimitExceeded: false path), so a transport-layer request or body size limit bounds it completely (and node's default maximum HTTP header size of 16 KB already bounds the request line, so multi-megabyte payloads need a body parser). The impact is that an opt-in hard limit fails open on one key spelling, not unbounded allocation from a small input.

Record
CVE-2026-82562
CVSS 4.0
6.3 MediumCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
CVSS 3.1
3.7 LowCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
Weakness
CWE-770
Updated
2026-11-02
OSV 6.3

qs.parse does not enforce arrayLimit on comma groups under bracket-push keys when throwOnLimitExceeded is set (incomplete fix for CVE-2026-2391)

Summary

When qs.parse is called with comma: true and throwOnLimitExceeded: true, a comma-separated value under a bracket-push key (a[]=1,2,3,4) is split into an array without being compared against arrayLimit, while the same value under a flat key (a=1,2,3,4), an indexed key (a[0]=), a nested key (a[b]=), or a dotted key (a.b= with allowDots) throws the documented RangeError. A single parameter such as a[]=1,2,2,... therefore produces an inner array of arbitrary length even though the caller opted into the hard limit. This is the []= key form that the fix for CVE-2026-2391 (qs 6.14.2) did not cover.

Details

In lib/parse.js, a comma-separated value under a []= key is split and then wrapped as a single nested element (val = [val], so that each a[]=x,y group counts as one element of the outer array). The arrayLimit check that 6.14.2 added for comma values runs after that wrap, so for []= parts it only ever saw the wrapper of length 1. 6.15.3 added a pre-split comma count so that an oversized value throws before it is allocated, but gated it on an isFlatArrayValue flag that parseValues set to false for any part containing []=, and did not pass it for object-valued input, so the gap remained.

PoC




var qs = require('qs');



var options = { comma: true, arrayLimit: 3, throwOnLimitExceeded: true };



qs.parse('a=1,2,3,4', options);   // RangeError: Array limit exceeded. Only 3 elements allowed in an array.



qs.parse('a[]=1,2,3,4', options); // { a: [ [ '1', '2', '3', '4' ] ] }  (no throw)



qs.parse('a[]=' + '1,'.repeat(1000000) + '1', { comma: true, arrayLimit: 20, throwOnLimitExceeded: true });



// no throw; a 1,000,001-element inner array is allocated



Fix

lib/parse.js, applied in 8859c37 on main and released as v6.16.0: the isFlatArrayValue gate is removed, so every comma-split value is counted against arrayLimit before splitting regardless of key form. An in-limit group under a[]= still counts as one element of the outer array, and the default (throwOnLimitExceeded: false) path is unchanged.

Affected versions

>=6.14.2 <6.16.0, fixed in v6.16.0.

v6.14.2 introduced arrayLimit enforcement for comma values (the fix for CVE-2026-2391) but only for values not under a []= key, and every release from v6.14.2 through v6.15.3 has the same gap. v6.14.0 and v6.14.1, where throwOnLimitExceeded exists but does not apply to any comma form, are covered by CVE-2026-2391 rather than this record. Earlier lines (6.7.x through 6.13.x) have comma but no throwOnLimitExceeded, so there is no hard cap on any comma path to bypass; releases before 6.7.0 have no comma option.

Impact

An unauthenticated attacker who can reach an application that parses untrusted query strings or urlencoded bodies with both comma: true and throwOnLimitExceeded: true (both non-default) can bypass the configured limit with a single a[]= parameter and force the parser to allocate an array proportional to the request size. The cost is strictly linear in the attacker-supplied bytes (about 0.1 microseconds and 6 to 7 retained bytes per input byte; the same out-of-memory threshold as the documented default throwOnLimitExceeded: false path), so a transport-layer request or body size limit bounds it completely (and node's default maximum HTTP header size of 16 KB already bounds the request line, so multi-megabyte payloads need a body parser). The impact is that an opt-in hard limit fails open on one key spelling, not unbounded allocation from a small input.

Record
CVE-2026-82562
CVSS 4.0
6.3 MediumCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N
Weakness
CWE-770
Updated
2026-11-02
OSVDEBIAN-CVE-2026-82562 6.3

Summary When qs.parse is called with comma: true and throwOnLimitExceeded: true, a comma-separated value under a bracket-push key (a[]=1,2,3,4) is split into an array without being compared against arrayLimit, while the same value under a flat key (a=1,2,3,4), an indexed key (a[0]=), a nested key (a[b]=), or a dotted key (a.b= with allowDots) throws the documented RangeError. A single parameter such as a[]=1,2,2,... therefore produces an inner array of arbitrary length even though the caller opted into the hard limit. This is the []= key form that the fix for CVE-2026-2391 (qs 6.14.2) did not cover. ### Details In lib/parse.js, a comma-separated value under a []= key is split and then wrapped as a single nested element (val = [val], so that each a[]=x,y group counts as one element of the outer array). The arrayLimit check that 6.14.2 added for comma values runs after that wrap, so for []= parts it only ever saw the wrapper of length 1. 6.15.3 added a pre-split comma count so that an oversized value throws before it is allocated, but gated it on an isFlatArrayValue flag that parseValues set to false for any part containing []=, and did not pass it for object-valued input, so the gap remained. #### PoC js var qs = require('qs'); var options = { comma: true, arrayLimit: 3, throwOnLimitExceeded: true }; qs.parse('a=1,2,3,4', options); // RangeError: Array limit exceeded. Only 3 elements allowed in an array. qs.parse('a[]=1,2,3,4', options); // { a: [ [ '1', '2', '3', '4' ] ] } (no throw) qs.parse('a[]=' + '1,'.repeat(1000000) + '1', { comma: true, arrayLimit: 20, throwOnLimitExceeded: true }); // no throw; a 1,000,001-element inner array is allocated #### Fix lib/parse.js, applied in 8859c37 on main and released as v6.16.0: the isFlatArrayValue gate is removed, so every comma-split value is counted against arrayLimit before splitting regardless of key form. An in-limit group under a[]= still counts as one element of the outer array, and the default (throwOnLimitExceeded: false) path is unchanged. ### Affected versions >=6.14.2 <6.16.0, fixed in v6.16.0. v6.14.2 introduced arrayLimit enforcement for comma values (the fix for CVE-2026-2391) but only for values not under a []= key, and every release from v6.14.2 through v6.15.3 has the same gap. v6.14.0 and v6.14.1, where throwOnLimitExceeded exists but does not apply to any comma form, are covered by CVE-2026-2391 rather than this record. Earlier lines (6.7.x through 6.13.x) have comma but no throwOnLimitExceeded, so there is no hard cap on any comma path to bypass; releases before 6.7.0 have no comma option. ### Impact An unauthenticated attacker who can reach an application that parses untrusted query strings or urlencoded bodies with both comma: true and throwOnLimitExceeded: true (both non-default) can bypass the configured limit with a single a[]= parameter and force the parser to allocate an array proportional to the request size. The cost is strictly linear in the attacker-supplied bytes (about 0.1 microseconds and 6 to 7 retained bytes per input byte; the same out-of-memory threshold as the documented default throwOnLimitExceeded: false path), so a transport-layer request or body size limit bounds it completely (and node's default maximum HTTP header size of 16 KB already bounds the request line, so multi-megabyte payloads need a body parser). The impact is that an opt-in hard limit fails open on one key spelling, not unbounded allocation from a small input.

Record
DEBIAN-CVE-2026-82562
CVSS 4.0
6.3 MediumCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Updated
2026-11-02
Show 13 moreShow less
OSVGHSA-x5fp-wj9c-mxmx 6.3

qs array-limit bypass via bracket-key comma parsing

Summary

qs v6.15.3 allows bracket-key input to bypass arrayLimit and throwOnLimitExceeded when comma: true. The input a[]=1,2,3,4 succeeds with arrayLimit: 3, while the equivalent plain-key input is rejected.

Affected version tested:

qs v6.15.3
commit 18d085e919dae70c8f1b200ab99323058edab2c2

Details

parseArrayValue() enforces the comma limit only for flat values. The a[] form is marked non-flat, so its comma-separated value is wrapped after parsing and the inner array is not checked. A single parameter can therefore materialize arbitrarily large arrays.

PoC

const qs = require('qs')
const options = { comma: true, arrayLimit: 3, throwOnLimitExceeded: true }

const result = qs.parse('a[]=1,2,3,4', options)
console.log(result.a[0].length) // 4; expected RangeError

const big = qs.parse('a[]=' + '1,'.repeat(1000000) + '1', { comma: true, arrayLimit: 20 })
console.log(big.a[0].length) // 1000001

On v6.15.3, the first input parses successfully and the second creates an array with 1,000,001 elements. The equivalent a=1,2,3,4 input throws RangeError as expected.

Impact

An attacker who can supply a query string or form body can bypass configured array limits and force excessive memory allocation, causing denial of service. The limit must be applied after comma splitting and before the resulting array is wrapped.

Record
GHSA-x5fp-wj9c-mxmx
CVSS 4.0
6.3 MediumCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N
CVSS 3.1
3.7 LowCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
Weakness
CWE-770
Updated
2026-11-02
OSVRHSA-2026:60866 9.1

Red Hat Security Advisory: Red Hat Hardened Images RPMs Security Update

Record
RHSA-2026:60866
CVSS 3.1
9.1 CriticalCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
Updated
2026-11-02
OSVRHSA-2026:62544 7.5

Red Hat Security Advisory: Red Hat Hardened Images RPMs Security Update

Record
RHSA-2026:62544
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Updated
2026-11-02
OSVRHSA-2026:63164 8.8

Red Hat Security Advisory: Red Hat Hardened Images RPMs bug fix and enhancement update

Record
RHSA-2026:63164
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Updated
2026-11-02
OSVUBUNTU-CVE-2026-82562 6.3

Summary When qs.parse is called with comma: true and throwOnLimitExceeded: true, a comma-separated value under a bracket-push key (a[]=1,2,3,4) is split into an array without being compared against arrayLimit, while the same value under a flat key (a=1,2,3,4), an indexed key (a[0]=), a nested key (a[b]=), or a dotted key (a.b= with allowDots) throws the documented RangeError. A single parameter such as a[]=1,2,2,... therefore produces an inner array of arbitrary length even though the caller opted into the hard limit. This is the []= key form that the fix for CVE-2026-2391 (qs 6.14.2) did not cover. ### Details In lib/parse.js, a comma-separated value under a []= key is split and then wrapped as a single nested element (val = [val], so that each a[]=x,y group counts as one element of the outer array). The arrayLimit check that 6.14.2 added for comma values runs after that wrap, so for []= parts it only ever saw the wrapper of length 1. 6.15.3 added a pre-split comma count so that an oversized value throws before it is allocated, but gated it on an isFlatArrayValue flag that parseValues set to false for any part containing []=, and did not pass it for object-valued input, so the gap remained. #### PoC js var qs = require('qs'); var options = { comma: true, arrayLimit: 3, throwOnLimitExceeded: true }; qs.parse('a=1,2,3,4', options); // RangeError: Array limit exceeded. Only 3 elements allowed in an array. qs.parse('a[]=1,2,3,4', options); // { a: [ [ '1', '2', '3', '4' ] ] } (no throw) qs.parse('a[]=' + '1,'.repeat(1000000) + '1', { comma: true, arrayLimit: 20, throwOnLimitExceeded: true }); // no throw; a 1,000,001-element inner array is allocated #### Fix lib/parse.js, applied in 8859c37 on main and released as v6.16.0: the isFlatArrayValue gate is removed, so every comma-split value is counted against arrayLimit before splitting regardless of key form. An in-limit group under a[]= still counts as one element of the outer array, and the default (throwOnLimitExceeded: false) path is unchanged. ### Affected versions >=6.14.2 <6.16.0, fixed in v6.16.0. v6.14.2 introduced arrayLimit enforcement for comma values (the fix for CVE-2026-2391) but only for values not under a []= key, and every release from v6.14.2 through v6.15.3 has the same gap. v6.14.0 and v6.14.1, where throwOnLimitExceeded exists but does not apply to any comma form, are covered by CVE-2026-2391 rather than this record. Earlier lines (6.7.x through 6.13.x) have comma but no throwOnLimitExceeded, so there is no hard cap on any comma path to bypass; releases before 6.7.0 have no comma option. ### Impact An unauthenticated attacker who can reach an application that parses untrusted query strings or urlencoded bodies with both comma: true and throwOnLimitExceeded: true (both non-default) can bypass the configured limit with a single a[]= parameter and force the parser to allocate an array proportional to the request size. The cost is strictly linear in the attacker-supplied bytes (about 0.1 microseconds and 6 to 7 retained bytes per input byte; the same out-of-memory threshold as the documented default throwOnLimitExceeded: false path), so a transport-layer request or body size limit bounds it completely (and node's default maximum HTTP header size of 16 KB already bounds the request line, so multi-megabyte payloads need a body parser). The impact is that an opt-in hard limit fails open on one key spelling, not unbounded allocation from a small input.

Record
UBUNTU-CVE-2026-82562
CVSS 4.0
6.3 MediumCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N
CVSS 3.1
3.7 LowCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
Updated
2026-11-02
OSVCLSA-2026-1790541933 No score

TuxCare security update for qs (2 CVEs)

TuxCare rebuilt qs to address 2 CVEs. Fixed in 6.15.3-tuxcare.1.

Record
CLSA-2026-1790541933
Updated
2026-11-02
OSVCLSA-2026-1791453817 No score

TuxCare security update for qs (1 CVE)

TuxCare rebuilt qs to address 1 CVE. Fixed in 6.10.7-tuxcare.3.

Record
CLSA-2026-1791453817
Updated
2026-11-02
OSVCLSA-2026-1791626353 No score

TuxCare security update for qs (1 CVE)

TuxCare rebuilt qs to address 1 CVE. Fixed in 6.10.3-tuxcare.3.

Record
CLSA-2026-1791626353
Updated
2026-11-02
OSVCLSA-2026-1792449761 No score

TuxCare security update for qs (3 CVEs)

TuxCare rebuilt qs to address 3 CVEs. Fixed in 6.14.2-tuxcare.1.

Record
CLSA-2026-1792449761
Updated
2026-11-02
OSVCLSA-2026-1793015982 No score

TuxCare security update for qs (1 CVE)

TuxCare rebuilt qs to address 1 CVE. Fixed in 6.13.0-tuxcare.4.

Record
CLSA-2026-1793015982
Updated
2026-11-02
OSVCLSA-2026-1793098692 No score

TuxCare security update for qs (1 CVE)

TuxCare rebuilt qs to address 1 CVE. Fixed in 6.14.0-tuxcare.4.

Record
CLSA-2026-1793098692
Updated
2026-11-02
OSVCLSA-2026-1793718727 No score

TuxCare security update for qs (1 CVE)

TuxCare rebuilt qs to address 1 CVE. Fixed in 6.10.4-tuxcare.4.

Record
CLSA-2026-1793718727
Updated
2026-11-03
OSVCLSA-2026-1793718812 No score

TuxCare security update for qs (1 CVE)

TuxCare rebuilt qs to address 1 CVE. Fixed in 6.11.2-tuxcare.4.

Record
CLSA-2026-1793718812
Updated
2026-11-03

Affected products

Affected packages

Affected packages
PackageAffectedFixed
qs
npm
6.14.2 to 6.15.3
6.16.0
qs
TuxCare:npm
From an advisory covering 2 CVEs
6.15.3-tuxcare.0 up to 6.15.3-tuxcare.1, plus listed versions
6.15.3
6.15.3-tuxcare.1
qs
TuxCare:npm
6.10.7-tuxcare.0 up to 6.10.7-tuxcare.3, plus listed versions
6.10.76.10.7-tuxcare.16.10.7-tuxcare.2
6.10.7-tuxcare.3
qs
TuxCare:npm
6.10.3-tuxcare.0 up to 6.10.3-tuxcare.3, plus listed versions
6.10.36.10.3-tuxcare.16.10.3-tuxcare.2
6.10.3-tuxcare.3
qs
TuxCare:npm
From an advisory covering 3 CVEs
6.14.2-tuxcare.0 up to 6.14.2-tuxcare.1, plus listed versions
6.14.2
6.14.2-tuxcare.1
qs
TuxCare:npm
6.13.0-tuxcare.0 up to 6.13.0-tuxcare.4, plus listed versions
6.13.06.13.0-tuxcare.16.13.0-tuxcare.26.13.0-tuxcare.3
6.13.0-tuxcare.4
qs
TuxCare:npm
6.14.0-tuxcare.0 up to 6.14.0-tuxcare.4, plus listed versions
6.14.06.14.0-tuxcare.16.14.0-tuxcare.26.14.0-tuxcare.3
6.14.0-tuxcare.4
qs
TuxCare:npm
6.10.4-tuxcare.0 up to 6.10.4-tuxcare.4, plus listed versions
6.10.46.10.4-tuxcare.16.10.4-tuxcare.26.10.4-tuxcare.3
6.10.4-tuxcare.4
qs
TuxCare:npm
6.11.2-tuxcare.0 up to 6.11.2-tuxcare.4, plus listed versions
6.11.26.11.2-tuxcare.16.11.2-tuxcare.26.11.2-tuxcare.3
6.11.2-tuxcare.4
node-qs
Debian:12
All versions, plus listed versions
6.11.0+ds+~6.9.7-36.11.0+ds+~6.9.7-46.13.0+ds+~6.9.16-16.14.1+ds+~6.14.0-16.15.0+ds+~6.15.0-1
Show 4 moreShow less
6.15.0+ds+~6.15.0-26.15.0+ds+~6.15.0-36.15.2+ds+~6.15.1-16.16.0+ds+~6.15.1-1
None known
Show 14 moreShow less
Affected packages
PackageAffectedFixed
node-qs
Debian:13
All versions, plus listed versions
6.13.0+ds+~6.9.16-16.14.1+ds+~6.14.0-16.15.0+ds+~6.15.0-16.15.0+ds+~6.15.0-26.15.0+ds+~6.15.0-36.15.2+ds+~6.15.1-16.16.0+ds+~6.15.1-1
None known
node-qs
Debian:14
before 6.16.0+ds+~6.15.1-1, plus listed versions
6.13.0+ds+~6.9.16-16.14.1+ds+~6.14.0-16.15.0+ds+~6.15.0-16.15.0+ds+~6.15.0-26.15.0+ds+~6.15.0-36.15.2+ds+~6.15.1-1
6.16.0+ds+~6.15.1-1
qs
npm
6.14.2 up to 6.16.0
6.16.0
grafana12.4
Red Hat:hummingbird:1
From an advisory covering 6 CVEs
before 0:12.4.9-0.4.hum1
0:12.4.9-0.4.hum1
grafana13.1
Red Hat:hummingbird:1
From an advisory covering 2 CVEs
before 0:13.1.3-0.4.hum1
0:13.1.3-0.4.hum1
grafana13.2
Red Hat:hummingbird:1
From an advisory covering 10 CVEs
before 0:13.2.1-0.1.hum1
0:13.2.1-0.1.hum1
node-qs
Ubuntu:Pro:14.04:LTS
All versions, plus listed versions
0.4.2-10.6.5-10.6.5-1ubuntu0.1~esm1
None known
node-qs
Ubuntu:16.04:LTS
All versions, plus listed versions
2.2.4-1
None known
node-qs
Ubuntu:18.04:LTS
All versions, plus listed versions
2.2.4-12.2.4-1ubuntu1
None known
node-qs
Ubuntu:Pro:20.04:LTS
All versions, plus listed versions
6.5.2-16.9.0+ds-16.9.1+ds-16.9.1+ds-1ubuntu0.1~esm1
None known
node-qs
Ubuntu:22.04:LTS
All versions, plus listed versions
6.9.4+ds-16.10.1+ds-16.10.2+ds+~6.9.7-16.10.3+ds+~6.9.7-1
None known
node-qs
Ubuntu:24.04:LTS
All versions, plus listed versions
6.11.0+ds+~6.9.7-36.11.0+ds+~6.9.7-4
None known
node-qs
Ubuntu:26.10
All versions, plus listed versions
6.14.1+ds+~6.14.0-16.15.2+ds+~6.15.1-1
None known
node-qs
Ubuntu:26.04:LTS
All versions, plus listed versions
6.13.0+ds+~6.9.16-16.14.1+ds+~6.14.0-1
None known

History

History
RecordedChangedSources
affected
affected, aliases, factsOSV
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-82562 is a medium vulnerability (CVSS 6.3) in Ljharb Qs, published August 29, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.54%, the 45th percentile. Fixed in qs 6.16.0.

References

Show 95 moreShow less
MoveEnter Open