loopbackio / loopbackio/loopback-next
Query parameter array parsing broken for >20 items after qs upgrade (CVE fix side effect)
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- TypeScript
- Sterne
- 5.1k
- Forks
- 1.1k
- Ø Merge
- 2 T. 21 Std.
- Gemergte PRs (30 T.)
- 27
Beschreibung
Describe the bug
Current Behavior
After the qs upgrade in commit https://github.com/loopbackio/loopback-next/commit/1eedfd5057c05ac683a9c9b71c3086b61267ab81 (to address https://github.com/advisories/GHSA-6rw7-vpxm-498p), query parameter arrays with more than 20 items are being converted to objects with numeric keys instead of arrays. This causes LoopBack's parameter validation to fail.
Expected Behavior
Query parameters in the format ?ids=1&ids=2&ids=3...&ids=25 should be parsed as an array regardless of the number of items (within reasonable limits).
Steps to Reproduce
Create an endpoint with an array parameter:
typescript@get('/test')
async test(
@param.array('ids', 'query', { type: 'string' })
ids: string[]
): Promise<any> {
return { ids };
}
- Make a request with 21+ repeated query parameters:
GET /test?ids=1&ids=2&ids=3...&ids=21&ids=22
Observe the validation error:
json{
"error": {
"statusCode": 400,
"name": "BadRequestError",
"message": "Invalid data [{\"0\":\"1\",\"1\":\"2\",...}] for parameter \"ids\".",
"code": "INVALID_PARAMETER_VALUE"
}
}
Root Cause
The qs library by default limits array indices to 20 (https://github.com/ljharb/qs#parsing-arrays). When more than 20 items are provided, it converts the array to an object with numeric keys to prevent DoS attacks with extremely large indices like a[999999999].
This is documented behavior in the qs library, and there is an ongoing discussion about this limitation, since it was introduced in a patch version instead of a breaking change version: https://github.com/ljharb/qs/issues/537
Impact
This breaks existing APIs that accept more than 20 array items via query parameters.
Proposed Solution
Configure qs with a higher arrayLimit option. The default of 20 is too restrictive.
I encourage the LoopBack team to contribute to the discussion in the qs issue thread (https://github.com/ljharb/qs/issues/537) to help get this resolved at the library level, and in the meantime provide a way for LoopBack applications to configure this limit.
Suggested approaches for LoopBack:
Make arrayLimit configurable via RestServer options so applications can set their own limits
Increase the default arrayLimit to a more reasonable value (e.g., 100 or 1000)
Document the workaround for applications that need to handle this
LoopBack version: 4.x (any version after the qs upgrade)
Node.js version: [applicable to all]
Operating system: [applicable to all]
Additional Context
Related CVE fix: https://github.com/advisories/GHSA-6rw7-vpxm-498p
qs documentation: https://github.com/ljharb/qs#parsing-arrays
Ongoing discussion in qs repo: https://github.com/ljharb/qs/issues/537
Logs
Additional information
No response
Reproduction
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne damit, die Abfrageanalyse über die REST-Serveroptionen und das im Issue beschriebene qs arrayLimit-Verhalten nachzuverfolgen. Vergleiche den Ansatz mit einem konfigurierbaren Limit mit dem Ansatz eines höheren Standardwerts und überprüfe anschließend, dass wiederholte Query-Parameter über 20 hinaus Arrays bleiben und die Parametervalidierung durchlaufen, ohne den DoS-Schutz zu entfernen.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- typescript
- Bereich
- api, backend
- Issue-Typ
- Bug
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 45/100