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

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

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

Начать курс

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

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

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

Самая распространенная атака. Злоумышленник внедряет вредоносный SQL-код через пользовательский ввод.

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

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

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

<?php
$stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $_GET['id']);
$stmt->execute();
$result = $stmt->get_result();
?>

2. XSS (Cross-Site Scripting)

Внедрение JavaScript-кода на страницу через непроверенные данные.

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

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

Защита: Экранируйте вывод через htmlspecialchars():

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

3. CSRF (Cross-Site Request Forgery)

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

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

<form action="/delete.php" method="POST">
    <input type="submit" value="Удалить аккаунт">
</form>

Защита: Добавьте CSRF-токен:

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

4. Небезопасное хранение паролей

Хранение паролей в открытом виде или с устаревшими хешами (MD5, SHA1).

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

<?php
$password = md5($_POST['password']);
// или
$password = sha1($_POST['password']);
?>

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

<?php
$hash = password_hash($_POST['password'], PASSWORD_BCRYPT);
// Проверка:
if (password_verify($input_password, $hash)) {
    echo "Пароль верный";
}
?>

5. Небезопасная работа с файлами (Local/Remote File Inclusion)

Включение файлов через пользовательский ввод без проверки.

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

<?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');
}
?>

6. Неверная настройка сессий

Использование предсказуемых идентификаторов сессий или отсутствие регенерации.

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

<?php
session_start();
$_SESSION['user_id'] = $user_id;
// Сессия не регенерируется после входа
?>

Защита:

<?php
session_start();
session_regenerate_id(true); // Регенерация ID после логина
$_SESSION['user_id'] = $user_id;
?>

7. Недостаточная валидация ввода

Доверие к любым данным от пользователя.

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

<?php
$email = $_POST['email'];
mail($email, "Тема", "Сообщение");
?>

Защита: Валидируйте и фильтруйте ввод:

<?php
$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
if ($email) {
    mail($email, "Тема", "Сообщение");
} else {
    echo "Некорректный email";
}
?>

8. Небезопасное использование unserialize()

Десериализация данных из ненадежных источников может привести к RCE (Remote Code Execution).

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

<?php
$data = unserialize($_GET['data']);
?>

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

<?php
$data = json_decode($_GET['data'], true);
?>

9. Утечка информации через ошибки

Вывод подробных сообщений об ошибках в production-среде.

Уязвимый код (php.ini):

display_errors = On
error_reporting = E_ALL

Защита: Настройте логирование вместо вывода ошибок:

display_errors = Off
error_reporting = E_ALL
log_errors = On
error_log = /var/log/php_errors.log

10. Отсутствие HTTPS и HSTS

Передача данных по незащищенному

Блоги

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