Si está usando JavaScript, asegúrese de que cualquier variable que cruce el
límite entre PHP y JavaScript se pase en el campo scope
de MongoDB\BSON\Javascript, no interpolada en la cadena
de JavaScript. Esto puede ocurrir al usar cláusulas $where
en consultas, comandos mapReduce y group, y cualquier otro momento en que pase
JavaScript a la base de datos.
Por ejemplo, supongamos que tenemos algo de JavaScript para saludar a un usuario en los registros de la base de datos. Podríamos hacer:
<?php
$m = new MongoDB\Driver\Manager;
// ¡No haga esto!
$username = $_GET['field'];
$cmd = new \MongoDB\Driver\Command( [
'eval' => "print('Hola, $username!');"
] );
$r = $m->executeCommand( 'dramio', $cmd );
?>Sin embargo, ¿qué pasaría si un usuario malicioso pasa algo de JavaScript?
<?php
$m = new MongoDB\Driver\Manager;
// ¡No haga esto!
$username = $_GET['field'];
// $username se establece en "'); db.users.drop(); print('"
$cmd = new \MongoDB\Driver\Command( [
'eval' => "print('Hola, $username!');"
] );
$r = $m->executeCommand( 'dramio', $cmd );
?>
Ahora MongoDB ejecuta la cadena de JavaScript
"print('Hola, '); db.users.drop(); print('!');".
Este ataque es fácil de evitar: use args para pasar
variables de PHP a JavaScript:
<?php
$m = new MongoDB\Driver\Manager;
$_GET['field'] = 'derick';
$args = [ $_GET['field'] ];
$cmd = new \MongoDB\Driver\Command( [
'eval' => "function greet(username) { print('Hola, ' + username + '!'); }",
'args' => $args,
] );
$r = $m->executeCommand( 'dramio', $cmd );
?>
Esto añade un argumento al ámbito de JavaScript, que se usa como argumento
para la función greet. Ahora si alguien intenta enviar
código malicioso, MongoDB imprimirá inocuamente
Hola, '); db.dropDatabase(); print('!.
Usar argumentos ayuda a prevenir que la entrada maliciosa se ejecute en la base de datos. Sin embargo, debe asegurarse de que su código no vuelva a ejecutar la entrada de todos modos. Lo mejor es evitar ejecutar cualquier JavaScript en el servidor desde el principio.
Se recomienda encarecidamente evitar el uso de la cláusula » $where
en consultas, ya que afecta significativamente al rendimiento. Siempre que sea
posible, use operadores de consulta normales o el » Marco de
Agregación.
Como alternativa al » MapReduce, que usa JavaScript, considere usar el » Marco de Agregación. A diferencia de Map/Reduce, usa un lenguaje idiomático para construir consultas, sin tener que escribir y usar el enfoque más lento de JavaScript que requiere Map/Reduce.
El comando » eval ha sido deprecado desde MongoDB 3.0 y también debe evitarse.