Je lisais mon fidèle livre O'Reilly et suis tombé sur un passage sur la façon dont Mongo, par nature, évite le bourbier des failles de type injection SQL.
Dans mon instinct, je pense que je comprends cela. Si des variables non anaturées sont passées dans des requêtes, elles ne peuvent pas sortir de la structure de requête orientée document avec un UNION
, JOIN
, une requête transformée en commentaire, etc.
Comment MongoDB évite le désordre d'injection SQL? Est-ce juste par nature de cette syntaxe de requête?
MongoDB évite le potentiel de problèmes en n'analysant pas.
Toute API, n'importe où, qui implique le codage des données utilisateur dans un texte formaté qui est analysé a le potentiel pour l'appelant et l'appelé d'être en désaccord sur la façon dont ce texte doit être analysé. Ces désaccords peuvent être des problèmes de sécurité lorsque les données sont mal interprétées en tant que métadonnées. Cela est vrai que vous parliez de chaînes de format printf, y compris du contenu généré par l'utilisateur en HTML ou de la génération de SQL.
Étant donné que MongoDB n'analyse pas le texte structuré pour savoir quoi faire, il n'y a aucune possibilité d'interprétation erronée des entrées utilisateur en tant qu'instructions, et donc aucun trou de sécurité possible.
Soit dit en passant, le conseil d'éviter les API qui nécessitent une analyse est l'élément 5 dans http://cr.yp.to/qmail/guarantee.html . Si vous êtes intéressé par l'écriture de logiciels sécurisés, les 6 autres suggestions méritent également d'être examinées.
Mise à jour (2018): La réponse originale telle que je l'ai donnée reste fidèle au meilleur de ma connaissance. Du point de ce qui est envoyé à MongoDB à ce qui est renvoyé, il n'y a pas d'attaque par injection SQL. Les attaques par injection que je connais se produisent en dehors de MongoDB et sont en fait des problèmes dans la façon dont les langues et les bibliothèques externes configurent la structure de données qui sera transmise à MongoDB. De plus, l'emplacement de la vulnérabilité réside dans la façon dont les données sont analysées pour devenir une structure de données. Par conséquent, la réponse originale décrit avec précision à la fois comment éviter les attaques par injection et ce qui vous met en danger.
Mais cette précision est un confort froid pour un programmeur qui est frappé par des attaques par injection de défauts qui n'étaient pas évidents dans son propre code. Peu d'entre nous font la distinction entre l'outil externe et toutes les couches entre notre code et cet outil externe. Et il n'en demeure pas moins qu'il faut de notre part une vigilance pour anticiper et stopper les attaques par injection. Avec tous les outils. Et cela restera le cas dans un avenir prévisible.
Pour résumer le MongoDB documentation
[~ # ~] bson [~ # ~]
Lorsqu'un programme client assemble une requête dans MongoDB, il crée un objet BSON, pas une chaîne. Ainsi, les attaques par injection SQL traditionnelles ne sont pas un problème.
Cependant, MongoDB n'est pas à l'abri des attaques par injection . Comme indiqué dans la même documentation, les attaques par injection sont toujours possibles car les opérations MongoDB permettent d'exécuter des expressions JavaScript arbitraires directement sur le serveur. La documentation va dans le détail:
Avec PHP mongoDB peut devenir vulnérable à l'injection No-SQL:
http://www.idontplaydarts.com/2010/07/mongodb-is-vulnerable-to-sql-injection-in-php-at-least/
Pour se protéger contre l'injection SQL, les clients peuvent utiliser les API de langue de MongoDB. De cette façon, toutes les entrées sont de simples valeurs - les commandes ne peuvent pas être injectées. A Java:
collection.find(Filters.eq("key", "input value"))
L'inconvénient est que vous ne pouvez pas facilement tester votre filtre. Vous ne pouvez pas le copier dans Shell de Mongo et le tester. Particulièrement problématique avec des filtres/requêtes plus grands et plus complexes.
MAIS!!! il y a aussi une API pour ne pas utiliser l'API du filtre - permettant d'analyser n'importe quel filtre json. Java exemple ci-dessous:
collection.find(BasicDBObject.parse("{key: "input value"}"));
C'est bien parce que vous pouvez copier le filtre directement dans le shell MongoDB pour le tester.
MAIS!!! (dernier mais, je le promets), cela est sujet à l'injection de NoSql. Java, où la valeur d'entrée est {$gt: ""}
.
collection.find(BasicDBObject.parse("{key: {$gt: ""}}"));
Dans ce dernier exemple, tout est retourné, même si nous voulions uniquement renvoyer les enregistrements spécifiques.
Voir ici une explication plus approfondie sur l'injection SQL lors de l'utilisation directe des filtres.
Une dernière chose. Je pense qu'il existe un moyen d'utiliser les deux filtres bruts tout en protégeant contre l'injection SQL. Par exemple, en Java, nous pouvons utiliser requêtes paramétrées de Jongo .
La base de données peut ne pas analyser le contenu, mais d'autres zones du code sont vulnérables.