PortSwigger · NoSQL Injection
Qué es
Bases de datos como MongoDB no usan SQL, pero también construyen consultas con lo que envía el usuario. Hay dos variantes: syntax injection (romper la sintaxis de la consulta, como en SQLi) y operator injection (colar operadores de MongoDB como $ne, $regex o $where en un JSON).
Labs completados
| # | Lab | Tipo |
|---|---|---|
| 1 | Detecting NoSQL injection | Syntax injection |
| 2 | Exploiting NoSQL operator injection to bypass authentication | Operator injection |
| 3 | Exploiting NoSQL injection to extract data | Syntax injection |
| 4 | Exploiting NoSQL operator injection to extract unknown fields | Operator injection |
Lo que me llevo
- Detección: una comilla en
?category=Gifts'da un error de MongoDB. ConGifts'||1||'la condición es siempre cierta y se ven productos ocultos. - Saltar el login: el login va en JSON, así que cambio los valores por operadores:
json
{"username":{"$regex":"admin.*"},"password":{"$ne":""}}"Usuario que empiece por admin y contraseña distinta de vacío" → entro como administrador.
- Extraer datos: en
/user/lookup?user=wiener'puedo inyectar JavaScript que evalúa MongoDB y preguntar carácter a carácter por la contraseña (' && this.password[0]=='a), igual que una Blind SQLi. - Campos desconocidos: con
$whereyObject.keys(this)descubro qué campos tiene el documento (por ejemplo, el token de reseteo de contraseña) y luego extraigo su valor.
Cómo se arregla
- Validar el tipo: si espero un texto, rechazar objetos (
{"$ne": ...}). - Usar las consultas parametrizadas del driver y desactivar la evaluación de JavaScript en el servidor (
$where).
