## Attaque par injection de scripts

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.

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open