Атака с помощью инъекций в скриптах

Если вы используете JavaScript, убедитесь, что все переменные, которые пересекают границу PHP-JavaScript, передаются в поле scope MongoDB\BSON\Javascript, а не интерполируются в строку JavaScript. Это может возникнуть при использовании предложений $where в запросах, командах mapReduce и group, а также в любое другое время, когда вы можете передать JavaScript в базу данных.

Например, предположим, что у нас есть некоторый JavaScript, чтобы приветствовать пользователя в журналах базы данных. Мы могли бы сделать:

<?php
$m
= new MongoDB\Driver\Manager;

// Не делайте так!!!
$username = $_GET['field'];

$cmd = new \MongoDB\Driver\Command( [
'eval' => "print('Привет, $username!');"
] );

$r = $m->executeCommand( 'dramio', $cmd );
?>

Однако что, если злоумышленник передаст какой-то JavaScript?

<?php
$m
= new MongoDB\Driver\Manager;

// Не делайте так!!!
$username = $_GET['field'];
// $username is set to "'); db.users.drop(); print('"

$cmd = new \MongoDB\Driver\Command( [
'eval' => "print('Привет, $username!');"
] );

$r = $m->executeCommand( 'dramio', $cmd );
?>

Теперь MongoDB выполнит строку JavaScript "print('Привет, '); db.users.drop(); print('!');". Эту атаку легко избежать: используйте args для передачи переменных из PHP в JavaScript:

<?php
$m
= new MongoDB\Driver\Manager;

$_GET['field'] = 'derick';
$args = [ $_GET['field'] ];

$cmd = new \MongoDB\Driver\Command( [
'eval' => "function greet(username) { print('Привет, ' + username + '!'); }",
'args' => $args,
] );

$r = $m->executeCommand( 'dramio', $cmd );
?>

Это добавляет аргумент в область JavaScript, которая используется в качестве аргумента для функции greet. Теперь, если кто-то попытается отправить вредоносный код, MongoDB безвредно напечатает Привет, '); db.dropDatabase(); print('!.

Использование аргументов помогает предотвратить выполнение вредоносного ввода базой данных. Тем не менее, вы должны убедиться, что ваш код не перевернётся и всё равно выполнит ввод! Лучше всего избегать выполнения любого JavaScript на сервере.

Настоятельно рекомендуется избегать предложения » $where clause с запросами, так как это существенно влияет на производительность. По возможности используйте либо обычные операторы запросов, либо » Aggregation Framework.

В качестве альтернативы » MapReduce, использующей JavaScript, рассмотрите возможность использования » Aggregation Framework. В отличие от Map/Reduce, он использует идиоматический язык для построения запросов, без необходимости писать и использовать более медленный подход JavaScript, который требуется для Map/Reduce.

Команда » eval устарела с MongoDB 3.0, и её также следует избегать.

add a note add a note

User Contributed Notes 1 note

up
-30
Robin
8 years ago
Shouldn't the second example have this

$_GET['field'] = "'); db.users.drop(); print('";

Before it sets $username?
To Top