Securité
Attaque par injection dans la requête
Si vous passez des paramètres $_GET dans vos requêtes, assurez-vous de les transtyper en chaînes de caractères avant. Les utilisateurs peuvent insérer des tableaux associatifs dans leurs requêtes GET, qui deviendront des requêtes non désirées.
Voici un exemple relativement inoffensif : supposez que vous récupérez les informations d'un utilisateur avec la requête http://www.example.com?username=bob. Votre application exécute la requête suivante : $collection->find(array("username" => $_GET['username'])).
Quelqu'un peut détourner ce comportement en appelant l'URL suivante : http://www.example.com?username[$ne]=foo, que PHP transformera automatiquement en un tableau associatif, exécutant ainsi la requête suivante : $collection->find(array("username" => array('$ne' => "foo"))), qui retournera tous les utilisateurs qui ne se nomment pas "foo" (tous vos utilisateurs, probablement).
Ceci est une attaque simple qui se contre tout aussi facilement : assurez-vous que les paramètres $_GET sont du type que vous attendez avant de les envoyer à la base de données (transtypez les en chaînes de caractères, dans ce cas).
Notez que ce type d'attaque peut être utilisée avec chaque itération de bases de données qui tente de localiser un document, y compris les mises à jour, les recherches/remplacements, et les effacement.
Merci à » Phil d'avoir mis le doigt sur ces possibilités.
Reportez-vous à » la documentation principale pour plus d'informations sur les injections SQL avec MongoDB.
Attaques par injection
Si vous utilisez Javascript, assurez-vous que toutes les variables qui passent par le lien PHP-vers-Javascript sont passées dans le champ scope de la classe MongoCode sans être interpolées dans la chaîne Javascript. Ceci peut survenir lors de l'utilisation de la méthode MongoDB::execute(), des clauses $where, MapReduces, group-bys, et à chaque fois que vous pouvez passer du Javascript dans la base de données.
Note:
MapReduce ignore le champ scope de la méthode MongoCode, mais il y a une option scope sur la commande qui peut être utilisée à la place.
Par exemple, supposons que nous avons du Javascript qui salut un utilisateur dans la base de données. Nous pouvons faire :
<?php // Ne faîtes pas ceci ! $username = $_POST['username']; $db->execute("print('Hello, $username!');"); ?>
Cependant, que se passe-t-il si un utilisateur passe le Javascript suivant ?
<?php // Ne faîtes pas ceci ! // $username vaut : "'); db.users.drop(); print('" $db->execute("print('Hello, $username!');"); ?>
Maintenant, MongoDB exécute le chaîne Javascript "print('Hello, '); db.users.drop(); print('!');". Ce type d'attaque est facile à contrer : utilisez scope pour passe les variables de PHP à Javascript :
<?php $scope = array("user" => $username); $db->execute(new MongoCode("print('Hello, '+user+'!');", $scope)); ?>
Ceci permet d'ajout une variable user au scope JavaScript. Maintenant, si quelqu'un tente d'envoyer du code malicieux, MongoDB affichera Hello, '); db.dropDatabase(); print('!.
L'utilisation de scope permet de prévenir d'exécution de code malicieux dans la base de données. Cependant, vous devez vous assurer que votre code ne tourne pas en rond et finisse par, au final, exécuter l'entrée utilisateur ! Par exemple, n'utilisez jamais la fonction Javascript eval sur des entrées utilisateurs :
<?php // Ne faîtes pas ceci ! // $jsShellInput vaut : "db.users.drop();" $scope = array("input" => $jsShellInput); $db->execute(new MongoCode("eval(input);", $scope)); ?>
Utilisez toujours scope et n'autorisez jamais la base de données à exécuter des entrées utilisateurs sous forme de code.