Si vous utilisez JavaScript, assurez-vous que toutes les variables qui
traversent la frontière PHP-JavaScript sont passées dans le champ
scope
de MongoDB\BSON\Javascript,
et non interpolées dans la chaîne JavaScript. Cela peut se produire lorsque
vous utilisez des clauses $where
dans les requêtes, les
commandes mapReduce et group, et à tout autre moment où vous pouvez passer
du JavaScript à la base de données.
Par exemple, supposons que nous avons un JavaScript pour saluer un utilisateur dans les logs de la base de données. Nous pourrions faire :
<?php
$m = new MongoDB\Driver\Manager;
// Ne faites pas ca !!!
$username = $_GET['field'];
$cmd = new \MongoDB\Driver\Command( [
'eval' => "print('Hello, $username!');"
] );
$r = $m->executeCommand( 'dramio', $cmd );
?>
Cependant, que se passe-t-il si un utilisateur malveillant passe du JavaScript ?
<?php
$m = new MongoDB\Driver\Manager;
// Ne faites pas ca !!!
$username = $_GET['field'];
// $username equivaut à "'); db.users.drop(); print('"
$cmd = new \MongoDB\Driver\Command( [
'eval' => "print('Hello, $username!');"
] );
$r = $m->executeCommand( 'dramio', $cmd );
?>
Maintenant MongoDB exécute la chaîne JavaScript
"print('Hello, '); db.users.drop(); print('!');"
.
Cette attaque est facile à éviter : utilisez args
pour passer
des variables de PHP à JavaScript :
<?php
$m = new MongoDB\Driver\Manager;
$_GET['field'] = 'derick';
$args = [ $_GET['field'] ];
$cmd = new \MongoDB\Driver\Command( [
'eval' => "function greet(username) { print('Hello, ' + username + '!'); }",
'args' => $args,
] );
$r = $m->executeCommand( 'dramio', $cmd );
?>
Cela ajoute un argument à la portée JavaScript, qui est utilisé comme argument
pour la fonction greet
. Maintenant si
quelqu'un essaie d'envoyer du code malveillant, MongoDB imprimera inoffensivement
Hello, '); db.dropDatabase(); print('!
.
Utiliser des arguments aide à empêcher l'exécution d'entrées malveillantes par la base de données. Cependant, vous devez vous assurer que votre code ne retourne pas et n'exécute pas l'entrée de toute façon ! Il est préférable d'éviter d'exécuter quelconque JavaScript sur le serveur en premier lieu.
Nous vous recommandons de rester à l'écart de la clause » $where dans les requêtes, car elle impacte significativement les performances. Dans la mesure du possible, utilisez soit des opérateurs de requête normaux, soit le » Framework d'agrégation.
Une alternative à » MapReduce, qui utilise JavaScript, est le » Framework d'agrégation. Contrairement à Map/Reduce, il utilise un langage idiomatique pour construire des requêtes, sans avoir à écrire et utiliser l'approche JavaScript plus lente que Map/Reduce nécessite.
La » commande eval a été dépréciée depuis MongoDB 3.0, et devrait également être évitée.