mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-03 13:58:55 +08:00
Translate security best practice to russian
This commit is contained in:
@ -111,7 +111,7 @@ All Rights Reserved.
|
|||||||
* **TBD** [Авторизация](security-authorization.md)
|
* **TBD** [Авторизация](security-authorization.md)
|
||||||
* **TBD** [Работа с паролями](security-passwords.md)
|
* **TBD** [Работа с паролями](security-passwords.md)
|
||||||
* **TBD** [Клиенты авторизации](security-auth-clients.md)
|
* **TBD** [Клиенты авторизации](security-auth-clients.md)
|
||||||
* **TBD** [Лучшие практики](security-best-practices.md)
|
* [Лучшие практики](security-best-practices.md)
|
||||||
|
|
||||||
|
|
||||||
Кеширование
|
Кеширование
|
||||||
|
|||||||
178
docs/guide-ru/security-best-practices.md
Normal file
178
docs/guide-ru/security-best-practices.md
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
Лучшие практики безопасности
|
||||||
|
============================
|
||||||
|
|
||||||
|
Ниже мы рассмотрим основные принципы безопасности и опишем, как избежать угроз при разработке на Yii.
|
||||||
|
|
||||||
|
Основные принципы
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Есть два основных принципа безопасности, независимо от того какое приложение разрабатывается:
|
||||||
|
|
||||||
|
1. Фильтрация ввода.
|
||||||
|
2. Экранирование вывода.
|
||||||
|
|
||||||
|
|
||||||
|
### Фильтрация ввода
|
||||||
|
|
||||||
|
Фильтрация ввода означает, что входные данные никогда не должны считаться безопасными и вы всегда должны проверять
|
||||||
|
являются ли полученные данные допустимыми. Например, если мы знаем, что сортировка может быть осуществлена только
|
||||||
|
по трём полям `title`, `created_at` и `status`, и поле может передаваться через ввод пользователем, лучше проверить
|
||||||
|
значение там где мы его получили:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$sortBy = $_GET['sort'];
|
||||||
|
if (!in_array($sortBy, ['title', 'created_at', 'status'])) {
|
||||||
|
throw new Exception('Invalid sort value.');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
В Yii, вы скорее всего будете использовать [валидацию форм](input-validation.md), чтоб делать такие проверки.
|
||||||
|
|
||||||
|
|
||||||
|
### Экранирование вывода
|
||||||
|
|
||||||
|
Экранирование вывода означает, что данные в зависимости от контекста должны экранироваться, например в контексте
|
||||||
|
HTML вы должны экранировать `<`, `>` и похожие специальные символы. В контексте JavaScript или SQL будет другой набор
|
||||||
|
символов. Так как ручное экранирование черевато ошибками Yii предоставляет различные утилиты для экранирования в
|
||||||
|
различных контекстах.
|
||||||
|
|
||||||
|
Как избежать SQL-иньекций
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
SQL-иньекции происходят когда текст запроса формируется склеивание неэкранированных строк, как показано ниже:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$username = $_GET['username'];
|
||||||
|
$sql = "SELECT * FROM user WHERE username = '$username'";
|
||||||
|
```
|
||||||
|
|
||||||
|
Вместо того, чтобы подставлять корректное имя пользователя злоумышленик может передать вам в приложение что-то вроде
|
||||||
|
`'; DROP TABLE user; --`.
|
||||||
|
В результате SQL будет следующий:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT * FROM user WHERE username = ''; DROP TABLE user; --'
|
||||||
|
```
|
||||||
|
|
||||||
|
Это валидный запрос, который будет искать пользователей с пустым именем, а затем удалит таблицу `user`, скорее всего
|
||||||
|
сломается приложение и будут потеряны данные (вы ведь делаете регулярное резервное копирование?).
|
||||||
|
|
||||||
|
Большинство запросов к базе данных в Yii происходит через [Active Record](db-active-record.md), который правильно
|
||||||
|
использует подготовленные запросы PDO внутри. При использовании подготовленных запросов невозможно манипулировать
|
||||||
|
запросом как это показано ниже.
|
||||||
|
|
||||||
|
Тем не менее, иногда нужны [сырые запросы](db-dao.md) или [построитель запросов](db-query-builder.md). В этом случае
|
||||||
|
вы должны использовать безопасные способы передачи данных. Если данные используются значения столбцов предпочтительнее
|
||||||
|
использовать подготовленные запросы:
|
||||||
|
|
||||||
|
```php
|
||||||
|
// query builder
|
||||||
|
$userIDs = (new Query())
|
||||||
|
->select('id')
|
||||||
|
->from('user')
|
||||||
|
->where('status=:status', [':status' => $status])
|
||||||
|
->all();
|
||||||
|
|
||||||
|
// DAO
|
||||||
|
$userIDs = $connection
|
||||||
|
->createCommand('SELECT id FROM user where status=:status')
|
||||||
|
->bindValues([':status' => $status])
|
||||||
|
->queryColumn();
|
||||||
|
```
|
||||||
|
|
||||||
|
Если данные используются в качестве имён столбцов или таблиц, то лучший путь это разрешить только предопределённый набор
|
||||||
|
значений:
|
||||||
|
|
||||||
|
```php
|
||||||
|
function actionList($orderBy = null)
|
||||||
|
{
|
||||||
|
if (!in_array($orderBy, ['name', 'status'])) {
|
||||||
|
throw new BadRequestHttpException('Only name and status are allowed to order by.')
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Если это невозможно, то имена столбцов и таблиц должны экранироваться. Yii использует специальный синтаксис
|
||||||
|
для экранирования для всех поддерживаемых баз данных:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$sql = "SELECT COUNT([[$column]]) FROM {{table}}";
|
||||||
|
$rowCount = $connection->createCommand($sql)->queryScalar();
|
||||||
|
```
|
||||||
|
|
||||||
|
Вы можете получить подробную информацию о синтаксисе в [Экранирование имён таблиц и столбцов](db-dao.md#quoting-table-and-column-names).
|
||||||
|
|
||||||
|
|
||||||
|
Как избежать XSS
|
||||||
|
----------------
|
||||||
|
|
||||||
|
XSS или крос-сайтинговый скриптинг становится возможен когда не экранированный выходной HTML попадает в браузер.
|
||||||
|
Например, если пользователь может ввести свой имя и вместо `Alexander` он вводит `<script>alert('Hello!');</script>`, то
|
||||||
|
все страницы которые его выводят без экранирования будут выполнять JavaScript `alert('Hello!');` и в результате
|
||||||
|
будет выводится окно сообщения в браузере. В зависимости от вебсайта вместо невинных скриптов с сообщениями могут быть
|
||||||
|
отправлены сообщения используя ваше имя или даже выполнять банковские операции.
|
||||||
|
|
||||||
|
В Yii избежать XSS легко. В основном есть два варианта:
|
||||||
|
|
||||||
|
1. Вы хотите вывести данные в виде обычного текста.
|
||||||
|
2. Вы хотите вывести данные в виде HTML.
|
||||||
|
|
||||||
|
Если вам нужно вывести простой текст, то екранировать лучше следующим образом:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?= \yii\helpers\Html::encode($username) ?>
|
||||||
|
```
|
||||||
|
|
||||||
|
Если нужно вывести HTML вам лучше воспользоваться HtmlPurifier:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?= \yii\helpers\HtmlPurifier::process($description) ?>
|
||||||
|
```
|
||||||
|
|
||||||
|
Обратите внимание, что обработка с помощью HtmlPurifier довольно тяжела, так что неплохо бы задуматься о кешировании.
|
||||||
|
|
||||||
|
Как избежать CSRF
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
CSRF это аббревиатура для межсайтинговой подмены запросов. Идея заключается в том, что многие приложения предполагают
|
||||||
|
что запросы приходящие от браузера отправляются самим пользователем. Это может быть неправдой.
|
||||||
|
|
||||||
|
Например, сайт `an.example.com` имеет URL `/logout`, который используя простой GET, разлогинивает пользователя. Пока
|
||||||
|
это запрос выполняется самим пользователем всё в порядке, но в один прекрасный день злоумышленники размещают код
|
||||||
|
`<img src="http://an.example.com/logout">` на форуме с большой посещаемостью. Браузер не делает никаких отличий
|
||||||
|
между запросом изображения и запросом страницы, так что когда пользователь откроет страницу с таким тегом `img`, он
|
||||||
|
разлогинится с сайта `an.example.com`.
|
||||||
|
|
||||||
|
Вот основная идея. Можно сказать, что в разлогировании пользователя нет ничего серъёзного, но отправить POST не намного
|
||||||
|
сложнее.
|
||||||
|
|
||||||
|
Для того чтоб избежать CSRF вы должны всегда:
|
||||||
|
|
||||||
|
1. Следуйте спецификациям HTTP, например запрос GET не должен менять состояние приложения.
|
||||||
|
2. Держите защиту CSRF в Yii включонной.
|
||||||
|
|
||||||
|
|
||||||
|
Как избежать нежелательного доступа к файлам
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
По умолчанию webroot сервера указывает на каталог `web` где лежит `index.php`. В случае виртуального хостинга
|
||||||
|
это может быть недостижимо, в конечном итоге весь код, конфиги и логи могут оказаться в webroot сервера.
|
||||||
|
|
||||||
|
Если это так, то нужно запретить доступ ко всему кроме директории `web`. Если на вашем хостинге такое невозможно,
|
||||||
|
рассмотрите возможность смены хостинга.
|
||||||
|
|
||||||
|
Как избежать отладочной информации и утилит в продуктиве
|
||||||
|
--------------------------------------------------------
|
||||||
|
|
||||||
|
В режиме отладки Yii отображает довольно подробные ошибки, которые полезны во время разработки. Дело в том, что
|
||||||
|
подробные ошибки удобны для нападающего, так как могут раскрыть структуру базы данных, параметров конфигурации и части
|
||||||
|
вашего кода. Никогда не запускайте продуктивное приложение с `YII_DEBUG` установленным в `true` в вашем `index.php`.
|
||||||
|
|
||||||
|
Вы никогда не должны включать Gii на продуктиве. Он может быть использован для получения информации о структуре
|
||||||
|
базы данных, кода и может быть просто переписан код с помощью генератора Gii.
|
||||||
|
|
||||||
|
Также следует избегат включения на продуктиве панели отладки, если только это деийствительно не необходимо.
|
||||||
|
Она раскрывает всё приложение и детали конфигурации. Если вам это абсолютно необходимо, проверьте дважды что доступ
|
||||||
|
ограничен только вашими IP-адресами.
|
||||||
Reference in New Issue
Block a user