Урок по треку PHP 8 мин

Сессии и безопасность PHP-приложения

SQL-инъекции, XSS, CSRF, пароли, сессии, загрузка файлов, unserialize.

Безопасность спрашивают на любом PHP-собесе: SQL-инъекции, XSS, CSRF, пароли и сессии. Важно не только назвать атаку, но и объяснить механику и защиту.

SQL-инъекция

// уязвимо
$pdo->query("SELECT * FROM users WHERE email = '$email'");

// безопасно
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(['email' => $email]);

Подготовленный запрос отделяет данные от SQL. Имена колонок и направление сортировки параметром не передать: их проверяют по белому списку. ORM параметризуют запросы сами, но сырые фрагменты (whereRaw, DB::raw) снова ваша ответственность.

XSS

Пользовательские данные выводят с экранированием по контексту:

<?= htmlspecialchars($name, ENT_QUOTES, 'UTF-8') ?>

Blade {{ }} и Twig экранируют автоматически, {!! !!} и |raw нет. Ссылки из пользовательских данных проверяют на схему (javascript: выполнится). strip_tags не защита. Дополнительный слой: заголовок Content-Security-Policy.

CSRF

Браузер прикладывает cookie к запросам с чужих сайтов. Защита: секретный токен в форме, сверяемый с сессией (во фреймворках включён по умолчанию), и cookie с SameSite=Lax. Метод POST сам по себе не защищает.

Пароли

$hash = password_hash($password, PASSWORD_DEFAULT);   // bcrypt, можно PASSWORD_ARGON2ID
if (password_verify($input, $hash)) { ... }
if (password_needs_rehash($hash, PASSWORD_DEFAULT)) { /* пересчитать */ }

MD5 и SHA-* для паролей не годятся: слишком быстрые. Токены генерируют random_bytes, сравнивают через hash_equals.

Сессии

  • Cookie сессии: HttpOnly, Secure, SameSite.
  • После входа session_regenerate_id(true) против фиксации сессии.
  • Короткий срок жизни, выход уничтожает сессию.
  • При нескольких серверах сессии в Redis, а не в файлах.
  • Блокировка сессии: файловые сессии блокируются на время запроса, параллельные AJAX-запросы одного пользователя выстраиваются в очередь (session_write_close как можно раньше).

Контроль доступа

Самая частая реальная уязвимость: проверили, что пользователь вошёл, но не проверили, что заказ его (IDOR). Права проверяют на каждом действии: политики Laravel, voters Symfony.

Другие атаки

  • Массовое присваивание: create($request->all()) с пустым $guarded. Нужны $fillable и валидированные данные.
  • Загрузка файлов: тип по содержимому (finfo), своё имя, хранение вне корня сайта.
  • unserialize внешних данных: PHP object injection. Используйте JSON.
  • SSRF: загрузка по URL от пользователя на внутренние адреса.
  • Обход каталога: ../ в путях к файлам, нормализация и проверка базового каталога.
  • Секреты: в переменных окружения, не в репозитории. composer audit для зависимостей.

Частые ошибки

  • Экранирование при сохранении вместо вывода.
  • Чёрные списки «опасных» слов.
  • Подробные ошибки в продакшене (display_errors=On).
  • Сообщение «пароль неверный для такого email», раскрывающее существование аккаунта.

Что спросят на собесе

  • Как защититься от SQL-инъекций и почему addslashes не подходит?
  • Что такое XSS и CSRF, чем они отличаются и как защищаться?
  • Как правильно хранить пароли?
  • Какие настройки нужны сессиям и зачем session_regenerate_id?
  • Что такое IDOR и массовое присваивание?

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.