Lors de l'utilisation de JavaScript, il faut s'assurer 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
on utilise des clauses $where dans les requĂȘtes, les
commandes mapReduce et group, et Ă tout autre moment oĂč il est possible de 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 ça !!!
$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 ça !!!
$username = $_GET['field'];
// $username équivaut à "'); 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 : utiliser 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, il faut s'assurer que le 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.
Il est recommandĂ© de rester Ă l'Ă©cart de la clause » $where dans les requĂȘtes, car elle impacte significativement les performances. Dans la mesure du possible, utiliser 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.