flawopen.com/Référence/Injection NoSQL MongoDB : quand une entrée modifie la requête
Injection NoSQL MongoDB : quand une entrée modifie la requête
MongoDB n’exécute pas SQL : la concaténation de chaînes SQL n’est donc pas en cause. Une injection NoSQL reste possible si l’application accepte un objet imbriqué non fiable à la place d’une valeur scalaire et le transmet à un filtre MongoDB. Il s’agit d’un défaut de validation des entrées de l’application, pas d’une CVE du serveur MongoDB.
En clair : une valeur devient une règle
Imaginez qu’un formulaire demande un nom, mais que l’agent accepte un ensemble d’instructions dans ce champ. La base suit les instructions au lieu de comparer un nom. Vérifiez le type attendu et construisez vous-même la règle de recherche.
Frontière de confiance : du JSON de la requête au filtre MongoDB
- Filtre de requête
- Document BSON interprété par MongoDB comme des comparaisons de champs et, le cas échéant, des opérateurs de requête.
- Injection d’opérateur
- L’application transmet une structure contrôlée par l’utilisateur à un emplacement où elle attendait une valeur littérale unique.
- Validation scalaire
- Vérifier le type, la longueur et le format autorisé avant que l’entrée puisse influer sur une opération de base de données.
- Projection
- Liste de champs choisie côté serveur pour limiter l’exposition accidentelle de données.
Comment le défaut se produit
Le point de terminaison attend un scalaire
Le contrat de l’API définit username comme une chaîne, mais un parseur JSON peut aussi produire des tableaux, objets, booléens et null.
L’application omet la validation du type
Le gestionnaire insère la valeur analysée directement dans un filtre créé par le serveur : l’objet reste une structure de requête au lieu de devenir une chaîne littérale.
MongoDB évalue la structure fournie
Si le document imbriqué contient des opérateurs de requête, le prédicat peut différer de la comparaison exacte prévue. Les enregistrements concernés dépendent de la requête et des contrôles d’autorisation de l’application.
La réponse détermine l’exposition
Les champs et le nombre d’enregistrements renvoyés dépendent de la projection, du point de terminaison et des privilèges du compte de base. Cela ne prouve pas à lui seul un contournement d’authentification ni un accès à toute la base.
La documentation officielle des pilotes MongoDB décrit cette frontière lorsqu’un point de terminaison convertit du JSON non validé en BSON et l’utilise comme filtre. Ce guide illustre ce défaut côté application. Il ne prétend pas que toutes les installations MongoDB sont vulnérables, ne cite aucune CVE serveur et ne fournit pas de recette de contournement d’authentification.
Exemples vulnérable et renforcé en Node.js
app.post("/users/lookup", async (req, res, next) => {
try {
// The route expects a string, but req.body.username is untrusted JSON.
const user = await users.findOne({ username: req.body.username });
res.json(user ? { username: user.username } : null);
} catch (error) {
next(error);
}
});
const loginSchema = z.object({
username: z.string().trim().min(1).max(128),
password: z.string().min(1).max(1024)
}).strict();
app.post("/login", async (req, res, next) => {
try {
const parsed = loginSchema.safeParse(req.body);
if (!parsed.success) return res.sendStatus(400);
const { username, password } = parsed.data;
// The application owns the filter key; input supplies only a string value.
const user = await users.findOne(
{ username },
{ projection: { _id: 1, username: 1, passwordHash: 1 } }
);
const passwordMatches = user &&
await argon2.verify(user.passwordHash, password);
if (!passwordMatches) return res.sendStatus(401);
return res.sendStatus(204); // Session creation is application-specific.
} catch (error) {
next(error);
}
});
Le parcours renforcé rejette les champs qui ne sont pas des chaînes avant tout accès à la base, n’accepte aucun filtre fourni par le client, construit une clé de filtre fixe dans le code de l’application, ne renvoie que les champs sélectionnés et vérifie le hachage du mot de passe après la recherche de l’utilisateur. L’exemple suppose que z désigne Zod, users la collection MongoDB et argon2 une bibliothèque de hachage configurée ; la création de session est volontairement hors périmètre.
Vérifications du correctif
- ✓Envoyez une chaîne normale et vérifiez que le gestionnaire interroge uniquement le champ exact défini par l’application.
- ✓Envoyez un objet, un tableau, un nombre, un booléen, null, un champ absent, une chaîne trop longue et une propriété inconnue ; vérifiez que le schéma les rejette avant tout appel à MongoDB.
- ✓Vérifiez que l’appel à la base reçoit un filtre construit par le serveur, jamais un filtre client ni un fragment JSON brut.
- ✓Vérifiez que la projection exclut les hachages de mots de passe et les champs sans rapport, et que le rôle de base ne possède que les droits nécessaires.
- ✓Hachez les mots de passe avec Argon2id ou bcrypt et vérifiez les hachages dans l’application ; n’interrogez jamais MongoDB avec le mot de passe reçu comme filtre.
Sources primaires
- MongoDB — bonnes pratiques des bibliothèques clientes : valider les entrées avant la conversion JSON vers BSON
- OWASP — aide-mémoire de sécurité NoSQL
- MongoDB — créer un filtre de requête (pilote C#) : la validation relève de l’application