Каждый день тысячи сайтов на PHP подвергаются атакам. Хакеры ищут дыры, чтобы украсть данные, сломать сайт или заразить его вирусами. В этой статье мы разберём две самые популярные угрозы — SQL-инъекции и XSS-атаки — и научимся от них защищаться. Вы узнаете, как писать код, который не стыдно показать профессионалам.
SQL-инъекции: как злоумышленники взламывают базы данных
SQL-инъекция — это когда хакер вставляет свой SQL-код в запрос через пользовательский ввод. Представьте, что вы спрашиваете у охранника: «Пропусти меня и всех моих друзей». Если охранник не проверит, кто именно ваши друзья, он может впустить грабителей. То же самое с базой данных.
Классический пример уязвимого кода:
$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
$result = mysqli_query($connection, $query);
Если злоумышленник введёт в поле username ' OR '1'='1, то запрос станет таким:
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = ''
Условие '1'='1' всегда истинно, поэтому база вернёт всех пользователей. Хакер войдёт под первым попавшимся аккаунтом.
Как защититься от SQL-инъекций
Главное правило: никогда не доверяйте пользовательскому вводу. Всегда используйте подготовленные выражения (prepared statements). Это как заказать пиццу по номеру: вы называете номер, а не перечисляете ингредиенты — повар не может добавить лишнего.
В PHP есть два расширения для работы с базой: PDO и MySQLi. Оба поддерживают подготовленные выражения. Вот пример на PDO:
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = :username AND password = :password');
$stmt->execute(['username' => $username, 'password' => $password]);
$user = $stmt->fetch();
А вот на MySQLi:
$stmt = $mysqli->prepare('SELECT * FROM users WHERE username = ? AND password = ?');
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
Подготовленные выражения отделяют код от данных, поэтому SQL-инъекция невозможна.
XSS-атаки: когда ваш сайт стреляет в пользователей
XSS (Cross-Site Scripting) — это внедрение вредоносного JavaScript-кода на страницу, который выполняется в браузере жертвы. Представьте, что в комментариях к посту кто-то оставил не текст, а скрипт, который крадёт куки. Ваш сайт становится оружием против ваших же посетителей.
Пример уязвимости:
echo "Привет, " . $_GET['name'];
Если злоумышленник передаст в параметре name такой код:
То браузер выполнит этот скрипт. А если вместо alert подставить код кражи куки, последствия будут печальными.
Как защититься от XSS
Основной метод — экранирование вывода. Все данные, которые выводите на страницу, нужно преобразовывать так, чтобы браузер воспринимал их как текст, а не как код. В PHP для этого есть функция htmlspecialchars().
Пример безопасного вывода:
$name = htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');
echo "Привет, " . $name;
Она заменяет опасные символы на HTML-сущности: < становится <, > — > и т.д. Браузер отобразит их как текст, а не как теги.
Также важно устанавливать заголовок Content-Security-Policy, который запрещает выполнение сторонних скриптов. И никогда не вставляйте пользовательские данные в атрибуты HTML без экранирования.
htmlspecialchars() с параметрами ENT_QUOTES и UTF-8 для всех данных, которые выводите в HTML. Это спасёт от большинства XSS.
Другие важные меры безопасности
Помимо SQL-инъекций и XSS, есть ещё несколько угроз, о которых стоит помнить. Например, CSRF (подделка межсайтовых запросов), когда злоумышленник заставляет пользователя выполнить нежелательное действие. Защита — использование токенов.
Ещё одна проблема — включённый вывод ошибок. В production-окружении ошибки не должны показываться пользователю, так как они могут выдать структуру базы или пути к файлам. Установите display_errors = Off в php.ini.
Также регулярно обновляйте PHP и библиотеки. Устаревшие версии содержат известные уязвимости.
Вот таблица с основными угрозами и методами защиты:
| Угроза | Метод защиты |
|---|---|
| SQL-инъекция | Подготовленные выражения (PDO, MySQLi) |
| XSS | Экранирование вывода (htmlspecialchars) |
| CSRF | Токены в формах |
| Утечка ошибок | Отключить display_errors на продакшене |
Заключение
Безопасность — это не роскошь, а необходимость. SQL-инъекции и XSS-атаки могут разрушить ваш проект и репутацию. Но если следовать простым правилам — использовать подготовленные выражения, экранировать вывод, обновлять ПО — вы закроете большинство дыр. Помните: лучше потратить час на защиту, чем потом неделю разбираться с последствиями взлома.
Начните с малого: проверьте свой код на уязвимости уже сегодня. И пусть ваш сайт будет крепостью для хакеров.



