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

1. SQL-инъекции: как не отдать базу данных злоумышленнику

SQL-инъекция — это когда хакер вставляет в ваш запрос свой SQL-код. Например, вместо имени пользователя он пишет что-то вроде ' OR '1'='1. Если вы просто подставляете данные в запрос, база данных может выполнить этот код. Результат — утечка данных или их удаление.

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

Пример неправильного кода:

$username = $_POST['username'];
$query = "SELECT * FROM users WHERE username = '$username'";
$result = mysqli_query($conn, $query);

Правильный вариант:

$stmt = $pdo->prepare('SELECT * FROM users WHERE username = :username');
$stmt->execute(['username' => $_POST['username']]);
$user = $stmt->fetch();
Правило №1: Никогда не доверяйте пользовательским данным. Всегда используйте подготовленные запросы.

2. XSS (межсайтовый скриптинг): как не дать вставить вредоносный код на вашу страницу

XSS — это когда злоумышленник вставляет JavaScript-код в вашу страницу. Например, через комментарии, поисковые запросы или профиль. Если вы выводите такой код без обработки, браузер его выполнит. Последствия: кража куки, перенаправление на фишинговые сайты.

Как защититься? Используйте htmlspecialchars() при выводе любых данных, которые ввел пользователь. Эта функция преобразует спецсимволы в HTML-сущности.

Пример:

echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');

Если вам нужно вывести HTML, который разрешен (например, в редакторе), используйте библиотеки типа HTMLPurifier. Но проще — не разрешать HTML вообще.

3. CSRF (межсайтовая подделка запроса): как защитить формы от подставных действий

CSRF — это атака, при которой злоумышленник заставляет пользователя выполнить действие на вашем сайте без его ведома. Например, перевести деньги или изменить пароль. Обычно это делается через ссылку или скрытую форму на другом сайте.

Как защититься? Добавьте в каждую форму CSRF-токен — случайную строку, которая генерируется на сервере и проверяется при отправке. Токен должен быть уникальным для сессии и формы.

Пример генерации токена:

session_start();
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

В форме:

Проверка на сервере:

if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
    die('Недействительный токен');
}
Лайфхак: Используйте фреймворки (Laravel, Symfony). Они уже имеют встроенную защиту от CSRF.

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

Многие разработчики хранят пароли к базе данных прямо в PHP-файлах в корне сайта. Это опасно: если злоумышленник получит доступ к файловой системе, он узнает все секреты. Храните конфигурационные файлы вне корневой директории веб-сервера. Если это невозможно, используйте .htaccess для блокировки доступа.

Пример .htaccess для защиты файла config.php:


  Order Deny,Allow
  Deny from all

Также не забывайте про файлы .env — они должны быть недоступны извне. В PHP можно использовать библиотеку vlucas/phpdotenv для загрузки переменных окружения.

5. Обработка ошибок: не показывайте хакеру внутренности вашего приложения

Когда на сайте возникает ошибка, PHP может вывести полную трассировку стека, включая пути к файлам, имена переменных и даже пароли. На продакшене это недопустимо. Отключите отображение ошибок и настройте логирование в файл.

В файле php.ini или в коде:

ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', '/var/log/php_errors.log');

Для пользователя показывайте только общее сообщение: «Что-то пошло не так. Попробуйте позже».

6. Использование HTTPS: шифруем все данные между браузером и сервером

Если ваш сайт работает по HTTP, все данные передаются в открытом виде. Это касается паролей, куки, токенов. Злоумышленник может перехватить их через незащищенную Wi-Fi сеть. Установите SSL-сертификат и настройте принудительное перенаправление на HTTPS.

Проверка в PHP:

if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') {
    header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
    exit;
}

Сейчас получить бесплатный SSL-сертификат легко через Let's Encrypt.

Правило №2: Храните пароли в зашифрованном виде (используйте password_hash() и password_verify()). Никогда не храните пароли в открытом виде.

Заключение

Безопасность PHP-приложения — это не разовая настройка, а постоянный процесс. Начните с малого: используйте подготовленные запросы, экранируйте вывод, добавьте CSRF-токены, уберите отображение ошибок и включите HTTPS. Эти простые шаги уже защитят вас от 90% типовых атак. Помните: безопасность — это не роскошь, а необходимость.

Студия WNDER