Безопасность PHP приложений: 10 главных уязвимостей для начинающих

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Безопасность PHP приложений: топ-10 уязвимостей для начинающих

PHP остаётся одним из самых популярных языков для веб-разработки, но его гибкость часто становится причиной серьёзных ошибок безопасности. Для новичка легко пропустить критическую уязвимость, которая может привести к утечке данных или полному взлому сервера. В этой статье мы разберём 10 самых распространённых уязвимостей PHP-приложений, покажем примеры опасного кода и научим вас правильно защищаться. Материал подготовлен специально для начинающих разработчиков, которые хотят писать безопасный код с первого дня.

1. SQL-инъекции (SQL Injection)

Это самая известная и опасная уязвимость. Она возникает, когда пользовательский ввод напрямую подставляется в SQL-запрос без экранирования. Злоумышленник может получить доступ к базе данных, изменить или удалить данные.

Опасный код:

<?php
$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = $id";
$result = mysqli_query($conn, $query);
?>

Как защититься: Используйте подготовленные запросы (prepared statements) с PDO или MySQLi.

<?php
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $_GET['id']]);
?>

2. XSS (Межсайтовый скриптинг)

XSS позволяет злоумышленнику внедрить вредоносный JavaScript-код на страницу, которая показывается другим пользователям. Это может привести к краже сессионных cookie или перенаправлению на фишинговые сайты.

Опасный код:

<?php
echo "Привет, " . $_GET['name'];
?>

Как защититься: Всегда экранируйте вывод с помощью htmlspecialchars().

<?php
echo "Привет, " . htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');
?>

3. CSRF (Межсайтовая подделка запроса)

CSRF-атака заставляет авторизованного пользователя выполнить нежелательное действие на сайте (например, сменить пароль или перевести деньги). Атака происходит, когда пользователь переходит по ссылке на стороннем сайте.

Как защититься: Используйте CSRF-токены для всех форм и запросов, изменяющих состояние.

<?php
session_start();
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
?>
<form method="POST">
    <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
    <button type="submit">Удалить аккаунт</button>
</form>

4. Небезопасная работа с файлами

Позволяет злоумышленнику читать или записывать произвольные файлы на сервере. Например, через path traversal или загрузку PHP-шеллов.

Опасный код:

<?php
include($_GET['page'] . '.php');
?>

Как защититься: Никогда не используйте пользовательский ввод в путях к файлам. Используйте белые списки допустимых значений.

<?php
$allowed_pages = ['home', 'about', 'contact'];
$page = $_GET['page'] ?? 'home';
if (in_array($page, $allowed_pages)) {
    include($page . '.php');
} else {
    include('404.php');
}
?>

5. Недостатки аутентификации и управления сессиями

Слабые пароли, отсутствие защиты от перебора, фиксация сессии — всё это открывает путь к захвату учётных записей.

Рекомендации:

  • Храните пароли только в хешированном виде через password_hash().
  • Используйте HTTPS для всех страниц с авторизацией.
  • Регенерируйте ID сессии после входа: session_regenerate_id(true).
  • Устанавливайте короткое время жизни сессии.

6. Небезопасное прямое указание объекта (IDOR)

IDOR возникает, когда пользователь может получить доступ к чужим данным, просто изменив ID в URL. Например, /profile.php?user_id=5.

Как защититься: Всегда проверяйте права доступа на сервере, а не только на клиенте.

<?php
$user_id = $_GET['user_id'];
if ($_SESSION['user_id'] !== $user_id && $_SESSION['role'] !== 'admin') {
    http_response_code(403);
    die('Доступ запрещён');
}
?>

7. Уязвимости при загрузке файлов

Позволяет загрузить вредоносный скрипт (например, PHP-шелл) вместо изображения. Это одна из самых частых причин взлома серверов.

Как защититься:

  • Проверяйте MIME-тип файла на сервере (не полагайтесь на расширение).
  • Переименовывайте файлы при сохранении.
  • Храните загруженные файлы вне корня веб-сервера.
<?php
$allowed_types = ['image/jpeg', 'image/png'];
if (!in_array($_FILES['file']['type'], $allowed_types)) {
    die('Недопустимый тип файла');
}
$new_name = bin2hex(random_bytes(16)) . '.jpg';
move_uploaded_file($_FILES['file']['tmp_name'], '/uploads/' . $new_name);
?>

8. Небезопасные десериализация объектов

Если ваше приложение использует unserialize() с пользовательскими данными, злоумышленник может выполнить произвольный код на сервере.

Как защититься: Никогда не передавайте непроверенные данные в unserialize(). Используйте JSON для обмена данными, где это возможно.

<?php                

Блоги

Рекомендаций по книгам