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

Я уверен, что говорить о безопасности нужно как можно раньше, это позволит избежать фатальных ошибок.

Главное правило касающееся безопасности звучит так: "Никогда не доверяйте пользователям". В первую очередь это правило касается данных которые они вводят. Возьмем пример из предыдущего урока, практику, в которой выводилось имя пользователя взятое из адреса: /users/nick. Код который реализует эту функциональность, рассчитывает на то, что в адресе используются только допустимые имена. Но что если попытаться открыть такой адрес:

# Запустите сервер для приложения созданного в предыдущем уроке
# Попробуйте открыть этот адрес в FireFox, потому что Chrome и Safari блокируют его,
# они знают про то, что такой код вредоносный.
http://localhost:8080/users/%3Cscript%3Ealert('attack!')%3B%3C%2Fscript%3E

XSS

В этом адресе закодирован код на 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 &lt;b&gt;bold&lt;/b&gt;
echo htmlspecialchars($str);

Получившаяся строка содержит безопасное описание тегов в виде html entities. Например &lt; отобразится как <, а &gt; как >. Возвращаясь к нашему примеру, правильный вывод в шаблоне должен пропускаться через функцию htmlspecialchars.

<h1><?= htmlspecialchars($id) ?></h1>

Теперь мы получим тот вывод, который изначально ожидали.

htmlspecialchars

Тоже самое касается любого другого вывода. В следующих уроках мы начнем активно использовать формы в которых подобная уязвимость встречается очень часто.

К сожалению PHP никак не защищает нас от подобных уязвимостей. Необходимо постоянно держать в голове такую возможность и не забывать вызывать функцию htmlspecialchars. На практике вы обязательно забудете), таков человеческий фактор. Это одна из причин почему популярны другие шаблонизаторы. В большинстве из них любые выводимые данные автоматически пропускаются через функцию подобную htmlspecialchars, что гарантирует безопасность без необходимости задумываться о ней.

Кроме XSS часто встречаются и другие виды атак, например SQL Injection, но для их понимания нужно иметь представление о работе базы данных

Самостоятельная работа

  1. Экранируйте вывод никнейма на странице пользователя

Дополнительные материалы

  1. Безопасность приложений (Хоть и написано что в Rails, но подходит для всех)
Мы учим программированию с нуля до стажировки и работы. Попробуйте наш бесплатный курс «Введение в программирование» или полные программы обучения по Node, PHP, Python и Java.

Хекслет

Подробнее о том, почему наше обучение работает →