Безопасность
Предотвращение межсайтового скриптинга
Межсайтововый скриптинг (также известный как XSS) — злонамеренный сбор информации пользователя через страницы веб-приложения. Чаще всего, производящий атаку, используя уязвимости приложения, включает в текст страницы JavaScript, VBScript, ActiveX, HTML или Flash. Делается это для получения информации других пользователей приложения и последующего её использования в нехороших целях. К примеру, плохо написанный форум может отображать сообщения пользователей без какой-либо проверки. Атакующий может вставить JavaScript-код в сообщение. Все, кто прочитает это сообщение, выполнит код на своём компьютере.
Чтобы не допустить XSS-атак, нужно всегда проверять то, что ввёл пользователь, прежде чем это отображать. Конечно, чтобы не допустить ввода скриптов, можно кодировать все HTML-сущности. В некоторых ситуациях такое поведение нежелательно, так как ввод HTML становится недоступен.
Yii включает в себя библиотеку HTMLPurifier и предоставляет разработчику полезный компонент CHtmlPurifier, который может отфильтровать весь вредоносный код при помощи тщательно проверенного белого листа. Также компонент делает код совместимым со стандартами.
CHtmlPurifier может быть использован и как виджет, и как фильтр. При использовании в качестве виджета CHtmlPurifier обрабатывает заключённое в него содержимое:
$this->beginWidget('CHtmlPurifier'); …этот текст будет подвергнут деликатной санобработке… <?php $this->endWidget();
Предотвращение подделки межсайтовых запросов
Подделка межсайтового запроса (CSRF) — атака, при которой сайт атакующего
заставляет браузер пользователя выполнить какое-либо действие на другом сайте.
К примеру, на сайте атакующего есть страница, содержащая тэг img
с атрибутом src
,
указывающим на сайт банка: http://bank.example/перевод?сумма=10000&кому=кулхацкеру
.
Если в браузере пользователя установлен cookie, позволяющий запомнить
его на сайте, посещение такой страницы вызовет перевод 10000 тугриков нехорошему
кулхацкеру. В CSRF, в отличие от межсайтового скриптинга, основанного на доверии
пользователя к некоторому сайту, используется доверие сайта определённому пользователю.
Для того, чтобы не допустить CSRF, важно придерживаться простого правила:
GET
— только для получения данных. Ничего менять при GET-запросах нельзя.
Для POST
необходимо использовать случайное значение, которое можно проверить
на сервере и убедиться, что запрос идёт оттуда, откуда нужно.
В Yii реализована защита от CSRF-атаки, проводимой через POST
. Защита основана
на хранении случайного значения в cookie и сравнения его со значением в POST
.
По умолчанию, защита от CSRF отключена. Для её включения необходимо настроить компонент CHttpRequest в файле конфигурации:
return array( 'components'=>array( 'request'=>array( 'enableCsrfValidation'=>true, ), ), );
Для отображения формы следует использовать CHtml::form вместо написания HTML-тэга. Данный метод позволяет автоматически включить случайное значение, используемое для проверки на CSRF, как скрытое поле формы.
Предотвращение атак через cookie
Защита cookie очень важна, так как именно в них чаще всего хранится ID сессии. Если злоумышленник получит ID сессии, он получит и всю информацию, которая в ней хранится.
Есть несколько способов предотвращения атак через cookie:
- Использовать SSL для создания защищённого соединения и передавать cookie только через него. Атакующий не сможет расшифровать содержимое передаваемых cookie.
- Вовремя объявлять сессию устаревшей, включая все cookie и маркеры сессии, для того, чтобы снизить возможность атаки.
- Предотвратить XSS, тем самым исключив захват cookie.
- Проверять данные cookie и определять, изменены ли они.
В Yii реализована проверка на изменения через подсчёт хэша HMAC от значений cookie.
По умолчанию проверка cookie отключена. Для её включения необходимо в конфигурации приложения настроить компонент CHttpRequest следующим образом:
return array( 'components'=>array( 'request'=>array( 'enableCookieValidation'=>true, ), ), );
При использовании проверки cookie, обращаться к ним необходимо через коллекцию
cookies, а не напрямую через $_COOKIES
:
// Получаем cookie с заданным именем $cookie=Yii::app()->request->cookies[$name]; $value=$cookie->value; … // Отсылаем cookie $cookie=new CHttpCookie($name,$value); Yii::app()->request->cookies[$name]=$cookie;