1
0
mirror of https://github.com/php/doc-ru.git synced 2026-03-25 08:12:14 +01:00
Files
archived-doc-ru/reference/mongodb/security.xml
Sergey Panteleev 300ffa98fb Исправление форматирования (#362)
[skip-spellcheck]
[skip-lint]
2021-10-21 09:47:52 +03:00

182 lines
8.2 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 4e0bf229045ff87d5f84469280bf0a6b195bfb8b Maintainer: sergey Status: ready -->
<!-- Reviewed: no -->
<book xml:id="mongodb.security" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Безопасность</title>
<article xml:id="mongodb.security.request_injection">
<title>Атака с помощью инъекций в запросе</title>
<para>
Если вы передаёте параметры <literal>$_GET</literal> (или <literal>$_POST</literal>)
своим запросам, убедитесь, что они сначала приводятся к строкам.
Пользователи могут вставлять ассоциативные массивы в запросы GET и POST, которые затем
могут стать нежелательными $-запросами.
</para>
<para>
Довольно безобидный пример. Предположим, вы ищете информацию о пользователе
по запросу <emphasis>http://www.example.com?username=bob</emphasis>.
Ваше приложение создаёт запрос
<literal>$q = new \MongoDB\Driver\Query( [ 'username' => $_GET['username'] ])</literal>.
</para>
<para>
Кто-то может подорвать это, получив
<emphasis>http://www.example.com?username[$ne]=foo</emphasis>, который PHP
волшебным образом превратит в ассоциативный массив, превратив ваш запрос в
<literal>$q = new \MongoDB\Driver\Query( [ 'username' => [ '$ne' => 'foo' ] ] )</literal>,
который вернёт всех пользователей, не имеющих имени "foo" (вероятно, всех ваших пользователей).
</para>
<para>
От этой атаки достаточно легко защититься: убедитесь, что параметры $_GET и $_POST
соответствуют ожидаемому типу, прежде чем отправлять их в базу данных.
PHP имеет функцию <function>filter_var</function>, чтобы помочь с этим.
</para>
<para>
Обратите внимание, что этот тип атаки может использоваться с любым взаимодействием с базой данных, которое
находит документ, включая команды update, upserts, delete и findAndModify.
</para>
<para>
Смотрите <link xlink:href="&url.mongodb.dochub.security;">основную документацию</link>
для получения дополнительной информации о проблемах SQL инъекций в MongoDB.
</para>
</article>
<article xml:id="mongodb.security.script_injection">
<title>Атака с помощью инъекций в скриптах</title>
<para>
Если вы используете JavaScript, убедитесь, что все переменные, которые пересекают границу
PHP-JavaScript, передаются в поле <literal>scope</literal>
<classname>MongoDB\BSON\Javascript</classname>, а не интерполируются в строку
JavaScript. Это может возникнуть при использовании предложений <literal>$where</literal>
в запросах, командах mapReduce и group, а также в любое другое время, когда вы можете
передать JavaScript в базу данных.
</para>
<para>
Например, предположим, что у нас есть некоторый JavaScript, чтобы приветствовать пользователя в журналах
базы данных. Мы могли бы сделать:
</para>
<programlisting role="php">
<![CDATA[
<?php
$m = new MongoDB\Driver\Manager;
// Не делайте так!!!
$username = $_GET['field'];
$cmd = new \MongoDB\Driver\Command( [
'eval' => "print('Привет, $username!');"
] );
$r = $m->executeCommand( 'dramio', $cmd );
?>
]]>
</programlisting>
<para>
Однако что, если злоумышленник передаст какой-то JavaScript?
</para>
<programlisting role="php">
<![CDATA[
<?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 );
?>
]]>
</programlisting>
<para>
Теперь MongoDB выполнит строку JavaScript
<literal>"print('Привет, '); db.users.drop(); print('!');"</literal>.
Эту атаку легко избежать: используйте <literal>args</literal> для передачи
переменных из 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('Привет, ' + username + '!'); }",
'args' => $args,
] );
$r = $m->executeCommand( 'dramio', $cmd );
?>
]]>
</programlisting>
<para>
Это добавляет аргумент в область JavaScript, которая используется в качестве аргумента
для функции <literal>greet</literal>. Теперь, если
кто-то попытается отправить вредоносный код, MongoDB безвредно напечатает
<literal>Привет, '); db.dropDatabase(); print('!</literal>.
</para>
<para>
Использование аргументов помогает предотвратить выполнение вредоносного ввода
базой данных. Тем не менее, вы должны убедиться, что ваш код не перевернётся
и всё равно выполнит ввод! Лучше всего избегать выполнения
<emphasis>любого</emphasis> JavaScript на сервере.
</para>
<para>
Настоятельно рекомендуется избегать предложения <link
xlink:href="&url.mongodb.docs;reference/operator/query/where/#considerations">$where
clause</link> с запросами, так как это существенно влияет на производительность.
По возможности используйте либо обычные операторы запросов, либо <link
xlink:href="&url.mongodb.docs;core/aggregation-pipeline">Aggregation
Framework</link>.
</para>
<para>
В качестве альтернативы <link
xlink:href="&url.mongodb.dochub.mapreduce;">MapReduce</link>, использующей
JavaScript, рассмотрите возможность использования <link
xlink:href="&url.mongodb.docs;core/aggregation-pipeline">Aggregation
Framework</link>. В отличие от Map/Reduce, он использует идиоматический язык
для построения запросов, без необходимости писать и использовать более медленный подход JavaScript,
который требуется для Map/Reduce.
</para>
<para>
Команда <link
xlink:href="&url.mongodb.docs;reference/command/eval/">eval</link>
устарела с MongoDB 3.0, и её также следует избегать.
</para>
</article>
</book>
<!-- 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
-->