Безопасность сайтов — тема, о которой редко говорят с новичками, но от которой зависит судьба любого бизнеса. Проблемы с безопасностью могут привести к утечке данных пользователей и даже к полному уничтожению сайта.
Исследования показывают, что подавляющее большинство сайтов имеют проблемы с безопасностью и подвержены атакам. Иногда случаются громкие взломы и утечки данных сотен тысяч и миллионов пользователей.
По этим причинам о безопасности нужно говорить как можно раньше. Это позволит избежать фатальных ошибок.
Чтобы обезопасить свой сайт, нужно помнить, что никогда нельзя доверять пользователям. Это правило касается данных, которые они вводят.
Возьмем пример из предыдущего урока — практику, в которой выводилось имя пользователя взятое из адреса: /users/nick.
Код, который реализует эту функциональность, рассчитывает на то, что в адресе используются только допустимые имена. Но что, если попытаться открыть такой адрес:
# Вот, что может произойти, если доверять данным,
# которые ввел пользователь, и не обрабатывать их.
http://localhost:8080/users/%3Cscript%3Ealert('attack!')%3B%3C%2Fscript%3E
В этом адресе закодирован код на JavaScript, который в оригинале выглядит так:
<script>
alert('attack!');
</script>
Проблема в том, что этот код не отобразился, а был вставлен в HTML как часть этого HTML. В итоге он выполнился.
Для браузера такой JS выглядит как часть страницы. Если попробовать открыть получившийся HTML, то он будет выглядеть так:
<h1><script>alert('attack!');</script></h1>
Такая атака называется XSS или Межсайтовый скриптинг. В этом случае на страницу внедряется вредоносный код, который выполняется в браузере пользователя и отправляет информацию о нем на сервер злоумышленника.
Вредоносный код может использовать авторизацию пользователя в веб-системе для получения к ней расширенного доступа или авторизационных данных пользователя.
XSS относится к одному из самых распространенных типов атак из-за большого количества уязвимостей даже на сайтах таких компаний, как Facebook.
Уязвимость возникает из-за доверия к пользовательским данным. В нашем коде вывод слага делается без предварительной обработки. Это неверно.
Дело в том, что браузер пытается интерпретировать как HTML всё, что похоже на HTML. Если в исходном коде встречается конструкция <текст>
, то браузер автоматически считает ее тегом.
Для вывода данных, которые не рассматриваются как HTML, нужно использовать специализированные функции, которые превращают теги в html entities:
<?php
$str = "A 'quote' is <b>bold</b>";
// Outputs: A 'quote' is <b>bold</b>
echo htmlspecialchars($str);
Получившаяся строка содержит безопасное описание тегов в виде html entities. Например, <
отобразится как <
, а >
— как >
. Если вернуться к нашему примеру, правильный вывод в шаблоне должен пропускаться через функцию htmlspecialchars()
:
<h1><?= htmlspecialchars($id) ?></h1>
Теперь мы получим тот вывод, который изначально ожидали:
Это касается и любого другого вывода. В следующих уроках мы начнем использовать формы, в которых подобная уязвимость встречается часто.
PHP не защищает от подобных уязвимостей. Необходимо постоянно держать в голове такую возможность и не забывать вызывать функцию htmlspecialchars()
.
На практике разработчики часто забывают использовать ее. Это одна из причин, почему популярны другие шаблонизаторы. В большинстве из них любые выводимые данные автоматически пропускаются через функцию, подобную htmlspecialchars()
. Это гарантирует безопасность.
Кроме XSS часто встречаются и другие виды атак, например, SQL Injection. Но чтобы понимать их, нужно знать, как работают базы данных.
Самостоятельная работа
- Экранируйте вывод никнейма и идентификатора пользователя на его странице, как сделано в теории урока.
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.