Безопасность веб-приложений — это не просто модный тренд, а необходимость. Если вы разрабатываете на Yii2, вам повезло: фреймворк уже включает мощные инструменты для борьбы с XSS и CSRF. Но знать, как их правильно использовать, — ваша задача. В этой статье разберём, что это за атаки, как Yii2 помогает от них защититься и какие ошибки могут свести всю защиту на нет.

Digital-студия WNDER

Что такое 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) ?>
// Выведет: &lt;script&gt;alert("XSS")&lt;/script&gt;

Если вы используете 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() с валидацией.
Лайфхак: Для API-запросов используйте 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-валидация. Эти два шага уже отсекут большинство атак.

Студия WNDER