1
0
mirror of https://github.com/php/doc-fr.git synced 2026-03-23 22:52:18 +01:00
Files
archived-doc-fr/reference/mongodb/security.xml
2026-03-02 13:40:31 +01:00

186 lines
6.5 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 3e871fe7eab38f9b0398569c57a1dd0c21e69652 Maintainer: Fan2Shrek Status: ready -->
<!-- Reviewed: yes -->
<chapter xml:id="mongodb.security" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Sécurité</title>
<section xml:id="mongodb.security.request_injection">
<title>Attaques par injection de requêtes</title>
<para>
Si on passe des paramètres <literal>$_GET</literal> (ou <literal>$_POST</literal>)
aux requêtes, il faut s'assurer de convertir en chaînes de caractères avant.
Les utilisateurs peuvent insérer des tableaux associatifs dans les requêtes
GET et POST, qui pourraient alors devenir des requêtes $ indésirables.
</para>
<para>
Un exemple assez anodin : supposez qu'on cherche les informations d'un
utilisateur avec la requête <emphasis>http://www.example.com?username=bob</emphasis>.
L'application crée la requête
<literal>$q = new \MongoDB\Driver\Query( [ 'username' => $_GET['username'] ])</literal>.
</para>
<para>
Cela fonctionne bien, mais quelqu'un pourrait subvertir cela en passant
<emphasis>http://www.example.com?username[$ne]=foo</emphasis>, que PHP
transformera magiquement en un tableau associatif, transformant le requête en
<literal>$q = new \MongoDB\Driver\Query( [ 'username' => [ '$ne' => 'foo' ] ] )</literal>,
qui renverra tous les utilisateurs dont le nom n'est pas "foo" (tous les utilisateurs, probablement).
</para>
<para>
C'est une attaque assez facile à contrer : il faut s'assurer que les paramètres
<literal>$_GET</literal> et <literal>$_POST</literal> sont du type attendu
avant d'envoyer à la base de données. PHP dispose de la fonction
<function>filter_var</function> pour aider.
</para>
<para>
À noter que ce type d'attaque peut être utilisé avec n'importe quelle interaction
avec la base de données qui localise un document, y compris les mises à jour,
les upserts, les suppressions et les commandes findAndModify.
</para>
<para>
Voir <link xlink:href="&url.mongodb.dochub.security;">la documentation principale</link>
pour plus d'informations sur les problèmes de type injection SQL avec MongoDB.
</para>
</section>
<section xml:id="mongodb.security.script_injection">
<title>Attaque par injection de scripts</title>
<para>
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
<literal>scope</literal> de <classname>MongoDB\BSON\Javascript</classname>,
et non interpolées dans la chaîne JavaScript. Cela peut se produire lorsque
on utilise des clauses <literal>$where</literal> 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.
</para>
<para>
Par exemple, supposons que nous avons un JavaScript pour saluer un utilisateur
dans les logs de la base de données. Nous pourrions faire :
</para>
<programlisting role="php">
<![CDATA[
<?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 );
?>
]]>
</programlisting>
<para>
Cependant, que se passe-t-il si un utilisateur malveillant passe du JavaScript ?
</para>
<programlisting role="php">
<![CDATA[
<?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 );
?>
]]>
</programlisting>
<para>
Maintenant MongoDB exécute la chaîne JavaScript
<literal>"print('Hello, '); db.users.drop(); print('!');"</literal>.
Cette attaque est facile à éviter : utiliser <literal>args</literal> pour passer
des variables de PHP à JavaScript :
</para>
<programlisting role="php">
<![CDATA[
<?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 );
?>
]]>
</programlisting>
<para>
Cela ajoute un argument à la portée JavaScript, qui est utilisé comme argument
pour la fonction <literal>greet</literal>. Maintenant si
quelqu'un essaie d'envoyer du code malveillant, MongoDB imprimera inoffensivement
<literal>Hello, '); db.dropDatabase(); print('!</literal>.
</para>
<para>
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 <emphasis>quelconque</emphasis> JavaScript sur le serveur
en premier lieu.
</para>
<para>
Il est recommandé de rester à l'écart de la clause <link
xlink:href="&url.mongodb.docs;reference/operator/query/where/#considerations">$where</link>
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 <link xlink:href="&url.mongodb.docs;core/aggregation-pipeline">Framework
d'agrégation</link>.
</para>
<para>
Une alternative à <link
xlink:href="&url.mongodb.dochub.mapreduce;">MapReduce</link>, qui utilise
JavaScript, est le <link
xlink:href="&url.mongodb.docs;core/aggregation-pipeline">Framework
d'agrégation</link>. 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.
</para>
<para>
La <link
xlink:href="&url.mongodb.docs;reference/command/eval/">commande eval</link>
a été dépréciée depuis MongoDB 3.0, et devrait également être évitée.
</para>
</section>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->