Безопасность веб-приложений — это не просто модный тренд, а необходимость. Если вы разрабатываете на Yii2, вам повезло: фреймворк уже включает мощные инструменты для борьбы с XSS и CSRF. Но знать, как их правильно использовать, — ваша задача. В этой статье разберём, что это за атаки, как Yii2 помогает от них защититься и какие ошибки могут свести всю защиту на нет.
Что такое XSS и CSRF и почему это важно
XSS (Cross-Site Scripting) — это когда злоумышленник внедряет свой JavaScript-код на вашу страницу, и он выполняется в браузере других пользователей. Представьте, что кто-то оставил комментарий с скриптом, который крадёт куки. Если вы выводите комментарий без экранирования, скрипт сработает.
CSRF (Cross-Site Request Forgery) — это когда злоумышленник заставляет браузер пользователя выполнить нежелательное действие на сайте, где тот авторизован. Например, перевод денег или смена пароля. Пользователь даже не заметит, потому что запрос уходит с его куками.
Обе атаки опасны, но Yii2 предоставляет встроенные механизмы для защиты. Главное — их не игнорировать.
Защита от XSS в Yii2
Yii2 автоматически экранирует вывод в виджетах и хелперах. Например, Html::encode() преобразует специальные символы в HTML-сущности. Но если вы используете чистый PHP-вывод, всё может быть печально.
Вот пример правильного экранирования:
// В контроллере
$comment = '<script>alert("XSS")</script>';
// Во view
<?= Html::encode($comment) ?>
// Выведет: <script>alert("XSS")</script>
Если вы используете Html::a(), Html::img() и другие хелперы, они тоже экранируют атрибуты. Но есть места, где нужно быть осторожным: например, при вставке HTML из Rich Text Editor. Тут поможет HtmlPurifier.
Yii2 имеет встроенный фильтр yii\helpers\HtmlPurifier, который очищает HTML от опасных тегов. Подключите его в конфигурации:
'components' => [
'htmlPurifier' => [
'class' => 'yii\helpers\HtmlPurifier',
],
],
А затем используйте:
$cleanHtml = Yii::$app->htmlPurifier->purify($dirtyHtml);
Html::encode() или HtmlPurifier для HTML-контента.
Защита от CSRF в Yii2
Yii2 по умолчанию включает CSRF-защиту для всех POST-запросов. Это реализовано через скрытое поле с токеном, который проверяется на сервере. Если токен не совпадает, запрос отклоняется.
В формах, созданных через ActiveForm, токен добавляется автоматически. Но если вы пишете форму вручную, не забудьте добавить:
<form method="post">
<input type="hidden" name="_csrf" value="<?= Yii::$app->request->csrfToken ?>">
...
</form>
Для AJAX-запросов нужно передавать токен в заголовке. Yii2 предоставляет yii\web\Request::$csrfParam и csrfToken. Вот пример на JavaScript:
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
fetch('/api/endpoint', {
method: 'POST',
headers: {
'X-CSRF-Token': csrfToken,
'Content-Type': 'application/json'
},
body: JSON.stringify({ data: 'value' })
});
Чтобы мета-тег был на странице, добавьте в layout:
<head>
<meta name="csrf-token" content="<?= Yii::$app->request->csrfToken ?>">
</head>
Если вы хотите отключить CSRF для определённых действий (например, для API), используйте свойство $enableCsrfValidation в контроллере:
public $enableCsrfValidation = false;
Но делайте это только для stateless-запросов, например, с API-ключами.
Сравнение методов защиты
В таблице ниже — основные инструменты Yii2 для борьбы с XSS и CSRF.
| Угроза | Инструмент Yii2 | Когда использовать |
|---|---|---|
| XSS | Html::encode() |
Для вывода простого текста |
| XSS | HtmlPurifier |
Для очистки HTML от пользователя |
| CSRF | ActiveForm |
Автоматически добавляет токен |
| CSRF | Yii::$app->request->csrfToken |
Для ручных форм и AJAX |
Лайфхаки и частые ошибки
Даже с встроенной защитой можно наступить на грабли. Вот несколько советов, которые сэкономят вам нервы.
- Не отключайте CSRF глобально. Лучше настроить исключения для конкретных действий.
- Используйте
HtmlPurifierс умом. Он может быть медленным, поэтому кешируйте очищенный HTML. - Проверяйте заголовки. Для AJAX-запросов добавляйте
X-Requested-With, чтобы отличать их от обычных. - Не доверяйте
$_GETи$_POSTнапрямую. Всегда используйтеYii::$app->request->get()иpost()с валидацией.
Yii::$app->request->csrfToken через заголовок X-CSRF-Token. Это удобно и безопасно.
Ещё одна ошибка — забыть про HttpOnly и Secure флаги для куки. В Yii2 это настраивается в компоненте session:
'session' => [
'cookieParams' => [
'httpOnly' => true,
'secure' => true, // только для HTTPS
],
],
Это защитит куки от кражи через XSS.
Что в итоге
Yii2 даёт разработчику всё необходимое для защиты от XSS и CSRF. Главное — не лениться использовать встроенные инструменты: экранировать вывод, добавлять CSRF-токены, очищать HTML через HtmlPurifier. И помните: безопасность — это процесс, а не галочка в чек-листе. Регулярно проверяйте код на уязвимости и следите за обновлениями фреймворка.
Начните с малого: проверьте, везде ли у вас стоит Html::encode() и включена ли CSRF-валидация. Эти два шага уже отсекут большинство атак.


