Query parameter array parsing broken for >20 items after qs upgrade (CVE fix side effect)
Los mantenedores suelen responder en 2 días
@KauanAfonso ya está trabajando en esto.
Desde el 10/6/2026.
- #11640 de @KauanAfonso — cerrado sin fusionar
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 45/100
- Tipo de issue
- Error
- Claridad
- Bastante claro
- Estado de actividad
- Estancado
- Stack tecnológico
- typescript
Línea de trabajo
Comienza siguiendo el análisis de consultas a través de las opciones del servidor REST y el comportamiento de qs arrayLimit descrito en el issue. Compara los enfoques de un límite configurable y de un valor predeterminado más alto, y después verifica que los parámetros de consulta repetidos más allá de 20 sigan siendo arrays y superen la validación de parámetros sin eliminar la protección contra DoS.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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
- Lenguaje dominante
- TypeScript
- Estrellas
- 5.1k
- Forks
- 1.1k
- Merge medio
- 4 d 13 h
- PR fusionados (30 d)
- 40
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de loopbackio/loopback-next
-
Docs good first issue help wanted
Dificultad 1/5 1-3 horas Aptitud para principiantes 68/100
loopbackio/loopback-next#683 · 3 comentarios ·
Los mantenedores suelen responder en 2 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 55/100
loopbackio/loopback-next#11726 ·
Los mantenedores suelen responder en 2 días
-
bug
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
loopbackio/loopback-next#11500 · 1 comentario · 1 reacción ·
Los mantenedores suelen responder en 2 días
-
@param.array throws INVALID_PARAMETER_VALUE:must be string if more than 20 elements are sentAbiertobug
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
loopbackio/loopback-next#11412 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
latest @loopback/graphql ESM export compatibility errorQuizá libre de nuevo @joelle-a-dev la tomó hace 54 días y no hay ningún pull request abierto. Abiertobug help wanted
Dificultad 3/5 1-2 días Aptitud para principiantes 48/100
loopbackio/loopback-next#11363 · 3 comentarios ·
Los mantenedores suelen responder en 2 días
Todos los issues de loopbackio/loopback-next
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
NaturalIntelligence/fast-xml-parser#890 · 1 comentario ·
Los mantenedores suelen responder en 3 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
zsviczian/obsidian-excalidraw-plugin#3000 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
pnpm/get.pnpm.io#68 ·
-
[BUG] Cloudflare KV binding 模式下 kvDriver.list() 沿用 EdgeOne 语义,字段名不匹配导致 key 格式下初始化 500 并耗尽 list 配额Posiblemente ocupada @wumingzhinu la tomó hoy. Abiertobug
Dificultad 2/5 1-3 horas Aptitud para principiantes 64/100
OpenListTeam/OpenList-Worker#125 ·
Los mantenedores suelen responder en 2 días
-
Android (vision-camera-location): HybridLocationManager never quits its HandlerThread on disposeAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
margelo/react-native-vision-camera#4217 ·
Los mantenedores suelen responder en 4 días