SeguridadAtaques de Inyección de Petición
Al pasar parámetros $_GET (o $_POST)
a una consulta, se ha de asegurar de que están convertidos a string.
Un usuario puede insertar un array asociativo en peticiones GET y POST, lo que
provocaría consultas $ no deseadas.
Un ejemplo aparentemente inofensivo: supongamos que estamos buscando información de un usuario
con la petición http://www.example.com?username=bob.
La aplicación realiza la consulta
$collection->find(array("username" => $_GET['username'])).
Alguien podría alterarlo realizando una consulta a
http://www.example.com?username[$ne]=foo, con lo que PHP
lo convertirá automáticamente a un array asociativo, creando la consulta
$collection->find(array("username" => array('$ne' => "foo"))),
que devolverá todos los usuarios con nombre distinto de "foo" (probablemente, todos).
Es sencillo defenderse de un ataque como éste: hay que asegurarse de que los parámetros
$_GET y $_POST son del tipo demandado antes de enviarlos a la base de datos
(en este caso, se han de convertir a string).
Tenga en cuenta que este tipo de ataque se puede usar con cualquier interacción con una base de datos
que localice documentos, incluyendo actualizaciones, busquedas con modificación, y
eliminaciones.
Gracias a Phil por apuntar esto.
Para más información sobre ataques tipo inyección SQL con MongoDB revise
la documentación principal.
Ataques de Inyección de Código
Si se está usando JavaScript, debemos asegurarnos que cualquier variable que cruce
los límites PHP-JavaScript se pasa en el campo scope de
MongoCode, y no interpolado en el código JavaScript.
Esto sucede al llamar a MongoDB::execute, consultas
$where, MapReduces, agrupaciones, y cualquier otra situación en que
se proporcione código JavaScript a la base de datos.
MapReduce ignora el campo scope de
MongoCode, pero hay una opción scope
disponible en el comando que puede utilizarse en su lugar.
Por ejemplo, supongamos que tenemos un código JavaScript para saludar a los usuarios
en los registros de la base de datos. Podríamos:
execute("print('Hola, $username!');");
?>
]]>
Pero, ¿qué ocurriría si un usuario malicioso metiera código JavaScript?
execute("print('Hola, $username!');");
?>
]]>
Ahora MongoDB ejecuta el código JavaScript
"print('Hola, '); db.users.drop(); print('!');".
Este ataque es fácil de evitar: utilice scope al
pasar variables de PHP a Javascript:
$username);
$db->execute(new MongoCode("print('Hello, '+user+'!');", $scope));
?>
]]>
Esto añade la variable user al ámbito de JavaScript. Si ahora
alguien quisiera añadir código malicioso, MongoDB imprimiría, sin causar daños,
Hello, '); db.dropDatabase(); print('!.
El uso de scope ayuda a prevenir que se ejecutene en la base
de datos entradas maliciosas. Sin embargo, debe asegurarse de que su código no
cambie y ejecute los datos de entrada. Por ejemplo, nunca utilice la función
eval de JavaScript con los datos de entrada de un usuario:
$jsShellInput);
$db->execute(new MongoCode("eval(input);", $scope));
?>
]]>
Use siempre scope y nunca permita que la base de datos ejecute
como código los datos de entrada del usuario.