Урок 18: Безопасность в Yii 2. Защита от XSS, CSRF, SQL-инъекций, хеширование паролей

На 18-ом уроке мы разберем один из самых важных аспектов веб-разработки, это безопасность. В Yii 2 есть мощные инструменты для защиты приложений и я покажу как ими правильно пользоваться. Мы затронем защиту от XSS, CSRF, SQL-инъекций, научимся валидировать данные, хранить пароли и защищать API.

Защита от XSS, CSRF и SQL-инъекций

XSS (межсайтовый скриптинг) это атака, при которой злоумышленник внедряет вредоносный код в страницы вашего приложения. Например, если пользователь вводит <script>alert('Hacked!')</script> в комментарий и этот код выполняется у других пользователей.

Yii 2 автоматически экранирует вывод данных в представлениях с помощью метода Html::encode(). Например:

php
<?= Html::encode($userComment) ?>

Для более сложной очистки (например, разрешая безопасные HTML-теги) используйте HtmlPurifier:

php
use yii\helpers\HtmlPurifier;

$cleanContent = HtmlPurifier::process($userContent);

CSRF (межсайтовая подделка запроса) это атака, при которой злоумышленник заставляет пользователя выполнить нежелательные действия от его имени. Yii 2 генерирует CSRF-токены для всех форм. Чтобы включить защиту:

  1. Добавьте <?= Html::csrfMetaTags() ?> в раздел <head> шаблона.
  2. В форме используйте ActiveForm, который автоматически добавляет скрытое поле с токеном.
  3. В контроллере убедитесь, что включена проверка:
php
public $enableCsrfValidation = true;

SQL-инъекции внедрение SQL-кода через пользовательский ввод. Защита в Yii 2:

  • Используйте Active Record или Query Builder, которые автоматически экранируют параметры.
  • Никогда не вставляйте сырые данные в SQL-запросы. Пример безопасного подхода:
php
$users = User::find()
    ->where('status = :status', [':status' => $userInput])
    ->all();

Практическая задача 1
Создайте форму обратной связи. Добавьте защиту от CSRF и обработайте пользовательский ввод с помощью HtmlPurifier, разрешив теги <b><i>.

Валидация и фильтрация пользовательских данных

Пользовательские данные это главный источник угроз. Все, что приходит из $_GET$_POST, кук, должно проверяться.

В Yii 2 валидация происходит в моделях. Например, правила для модели ContactForm:

php
public function rules() {
    return [
        [['name', 'email'], 'required'],
        ['email', 'email'],
        ['phone', 'match', 'pattern' => '/^\+7\d{10}$/'],
        ['message', 'string', 'max' => 1000],
    ];
}

Для фильтрации данных используйте filter в правилах. Например, обрезать пробелы:

php
['username', 'trim']

Создание кастомного валидатора
Допустим, нужно проверить номер телефона:

php
public function validatePhoneNumber($attribute) {
    if (!preg_match('/^\+7\d{10}$/', $this->$attribute)) {
        $this->addError($attribute, 'Номер должен быть в формате +7XXXXXXXXXX.');
    }
}

Практическая задача 2
Добавьте в модель User правило валидации для пароля: минимум 8 символов, обязательные буквы и цифры.

Хранение паролей: хеширование

Хранить пароли в открытом виде, очень грубая ошибка. Yii 2 предоставляет компонент security, который использует алгоритм bcrypt.

Регистрация пользователя

php
use Yii;

$user = new User();
$user->password_hash = Yii::$app->security->generatePasswordHash($password);
$user->save();

Проверка пароля при входе

php
if (Yii::$app->security->validatePassword($password, $user->password_hash)) {
    // Пароль верный
}

Советы

  • Никогда не используйте md5() или sha1() для паролей.
  • Обновляйте хеши при смене алгоритмов (например, через password_needs_rehash).

Практическая задача 3
Реализуйте смену пароля в личном кабинете. Убедитесь, что новый пароль хешируется.

Защита API-эндпоинтов

API уязвимы к тем же угрозам, что и веб-приложения, плюс добавляются риски подбора токенов и DDoS.

Аутентификация
Используйте токены. Например, в headers запроса:

php
use yii\filters\auth\HttpBearerAuth;

public function behaviors() {
    $behaviors = parent::behaviors();
    $behaviors['authenticator'] = [
        'class' => HttpBearerAuth::class,
    ];
    return $behaviors;
}

Ограничение запросов (Rate Limiting)
Защита от DDoS:

php
use yii\filters\RateLimiter;

public function behaviors() {
    return [
        'rateLimiter' => [
            'class' => RateLimiter::class,
            'enableRateLimitHeaders' => true,
        ],
    ];
}

Всегда используйте HTTPS для API. В Yii можно принудительно перенаправлять запросы:

php
if (!Yii::$app->request->isSecureConnection) {
    throw new \yii\web\ForbiddenHttpException('Доступ только по HTTPS.');
}

Практическая задача 4
Создайте API-метод для получения списка пользователей. Добавьте аутентификацию по токену и ограничение в 10 запросов в минуту.

Безопасность это не пункт в чек-листе, а непрерывный процесс. Всегда обновляйте зависимости, проверяйте код на уязвимости и тестируйте защиту.

Полный курс с уроками по Yii 2 для начинающих: https://max-gabov.ru/yii-2-dlya-nachinaushih

Поделиться статьей:
Поддержать автора блога

Поддержка автора осуществляется с помощью специальной формы ниже, предоставленной сервисом «ЮMoney». Все платёжные операции выполняются на защищённой странице сервиса, что обеспечивает их корректность и полную безопасность.

Персональные рекомендации
Оставить комментарий