Безопасность PHP приложений: топ-10 уязвимостей на практике

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

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

Начать курс

Безопасность PHP приложений: топ-10 уязвимостей на практике

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

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

Самая опасная и распространённая уязвимость. Атакующий вводит SQL-код через поля ввода, получая доступ к базе данных.

Уязвимый код:

$username = $_POST['username'];
$query = "SELECT * FROM users WHERE username = '$username'";

Атака: Ввод ' OR '1'='1 превращает запрос в SELECT * FROM users WHERE username = '' OR '1'='1', возвращая всех пользователей.

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

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

2. XSS (Cross-Site Scripting)

Атакующий внедряет JavaScript-код, который выполняется в браузере жертвы. Бывает трёх типов: reflected, stored и DOM-based.

Уязвимый код (stored XSS):

echo "<div>" . $comment . "</div>";

Защита: Экранируйте вывод с помощью htmlspecialchars():

echo "<div>" . htmlspecialchars($comment, ENT_QUOTES, 'UTF-8') . "</div>";

Для HTML-контента используйте библиотеки типа HTML Purifier.

3. CSRF (Cross-Site Request Forgery)

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

Защита: Внедрите CSRF-токены:

// Генерация токена
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));

// В форме
echo '<input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '">';

// Проверка
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
    die('CSRF-атака обнаружена');
}

4. Path Traversal (Обход каталогов)

Атакующий манипулирует путями к файлам, чтобы получить доступ к системным файлам (/etc/passwd и т.д.).

Уязвимый код:

$file = $_GET['file'];
include("pages/" . $file);

Защита: Используйте белые списки или функцию basename():

$allowed = ['home', 'about', 'contact'];
$file = basename($_GET['file']);
if (in_array($file, $allowed)) {
    include("pages/$file.php");
} else {
    die('Недопустимый файл');
}

5. File Upload Vulnerabilities (Уязвимости загрузки файлов)

Атакующий загружает PHP-скрипт вместо изображения, получая удалённый доступ к серверу.

Защита:

  • Проверяйте MIME-тип файла: $_FILES['file']['type']
  • Используйте finfo для определения реального типа
  • Запрещайте выполнение скриптов в папке загрузок через .htaccess
  • Генерируйте уникальные имена файлов: md5(uniqid()) . '.jpg'
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $_FILES['file']['tmp_name']);
$allowed = ['image/jpeg', 'image/png'];
if (!in_array($mime, $allowed)) {
    die('Недопустимый тип файла');
}

6. Session Fixation (Фиксация сессии)

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

Защита: После успешной аутентификации регенерируйте ID сессии:

session_regenerate_id(true);

Также установите параметры куки: session_set_cookie_params(['httponly' => true, 'secure' => true, 'samesite' => 'Strict']);

7. Command Injection (Внедрение команд)

Атакующий выполняет системные команды через уязвимые функции типа exec(), system() или shell_exec().

Уязвимый код:

$domain = $_GET['domain'];
echo shell_exec("ping -c 1 $domain");

Защита: Используйте escapeshellarg() или escapeshellcmd():

$domain = escapeshellarg($_GET['domain']);
echo shell_exec("ping -c 1 $domain");

8. Insecure Deserialization (Небезопасная десериализация)

PHP автоматически восстанавливает объекты из сериализованных данных, что может привести к удалённому выполнению кода.

Защита: Никогда не десериализуйте данные от пользователя. Используйте JSON вместо сериализации:

$data = json_decode($_POST['data'], true);

Если нужна сериализация — применяйте белые списки классов через unserialize() с callback-функцией.

9. Missing Authentication Checks (Отсутствие проверки аутентификации)

Разработчики часто забывают защитить административные страницы или API-эндпоинты.

Защита: Создайте middleware для проверки сессии:

function requireAuth() {
    if (!isset($_SESSION['user_id'])) {                

Блоги

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