Статьи

Межсайтовые скриптовые атаки (XSS)

Атака с использованием межсайтовых сценариев является одной из 5 самых популярных атак безопасности, которые проводятся ежедневно в Интернете, и ваши PHP-сценарии могут быть невосприимчивы.

Также известная как XSS, эта атака представляет собой тип атаки с использованием кода, которая становится возможной благодаря неправильной проверке пользовательских данных, которые обычно вставляются на страницу через веб-форму или с использованием измененной гиперссылки. Внедренный код может быть любым вредоносным кодом на стороне клиента, таким как JavaScript, VBScript, HTML, CSS, Flash и другие. Код используется для сохранения вредоносных данных на сервере или выполнения вредоносных действий в браузере пользователя.

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

Обучение на примере

Давайте возьмем следующий фрагмент кода.

<form action="post.php" method="post"> <input type="text" name="comment" value=""> <input type="submit" name="submit" value="Submit"> </form> 

Здесь у нас есть простая форма, в которой есть текстовое поле для ввода данных и кнопка отправки. После отправки формы она отправит данные в post.php для обработки. Допустим, все, post.php делает post.php — выводит данные примерно так:

 <?php echo $_POST["comment"]; 

Без какой-либо фильтрации хакер может отправить следующее через форму, которая генерирует всплывающее окно в браузере с сообщением «взломан».

  <Скрипт> оповещения ( "взломан") </ скрипт> 

Этот пример, несмотря на то, что он является злым по своей природе, похоже, не приносит большого вреда. Но подумайте о том, что может произойти в коде JavaScript, написанном для кражи cookie-файла пользователя и извлечения из него конфиденциальной информации? Существуют гораздо худшие XSS-атаки, чем простой вызов alert() .

Атаки с использованием межсайтовых сценариев можно сгруппировать в две основные категории в зависимости от способа доставки вредоносной нагрузки: непостоянный XSS и постоянный XSS. Позвольте мне подробно обсудить каждый тип.

Непостоянный XSS

Также известная как отраженная атака XSS, означающая, что фактический вредоносный код не хранится на сервере, а скорее проходит через него и представляется жертве, является более популярной стратегией XSS из двух методов доставки. Атака запускается из внешнего источника, например, из сообщения электронной почты или стороннего веб-сайта.

Вот пример части простого скрипта с результатами поиска:

 <?php // Get search results based on the query echo "You searched for: " . $_GET["query"]; // List search results ... 

Примером может быть очень небезопасная страница результатов, где поисковый запрос отображается обратно пользователю. Проблема в том, что переменная $_GET["query"] не проверена или не экранирована, поэтому злоумышленник может отправить жертве следующую ссылку:

  http://example.com/search.php?query= <скрипт> оповещения ( "взломан") </ скрипт> 

Без проверки страница будет содержать:

 You searched for: <script>alert("hacked")</script> 

Постоянный XSS

Этот тип атаки происходит, когда вредоносный код уже прошел процесс проверки и сохраняется в хранилище данных. Это может быть комментарий, файл журнала, сообщение с уведомлением или любой другой раздел на веб-сайте, который требует одновременного ввода данных пользователем. Позже, когда эта конкретная информация будет представлена ​​на веб-сайте, вредоносный код будет выполнен.

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

 <?php file_put_contents("comments.txt", $_POST["comment"], FILE_APPEND); 

В другом месте содержимое comments.txt показывается посетителям:

 <?php echo file_get_contents("comments.txt"); 

Когда пользователь отправляет комментарий, он сохраняется в файле данных. Затем весь файл (таким образом, вся серия комментариев) отображается для читателей. Если вредоносный код будет отправлен, он будет сохранен и отображен как есть без какой-либо проверки или экранирования.

Предотвращение межсайтовых скриптовых атак

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

Первое правило, которое необходимо «применять» в любой веб-среде (будь то разработка, подготовка или производство), — это никогда не доверять данным, поступающим от пользователя или из любых других сторонних источников. Это не может быть подчеркнуто достаточно. Каждый бит данных должен быть проверен на входе и экранирован на выходе. Это золотое правило предотвращения XSS.

Чтобы реализовать надежные меры безопасности, предотвращающие атаки XSS, мы должны помнить о проверке данных, их очистке и выходе из процесса.

Проверка данных

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

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

 <?php // validate a US phone number if (preg_match('/^((1-)?d{3}-)d{3}-d{4}$/', $phone)) { echo $phone . " is valid format."; } 

Санация данных

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

 <?php // sanitize HTML from the comment $comment = strip_tags($_POST["comment"]); 

Иногда проверка данных и их дезинфекция / нормализация могут идти рука об руку.

 <?php // normalize and validate a US phone number $phone = preg_replace('/[^d]/', "", $phone); $len = strlen($phone); if ($len == 7 || $len == 10 || $len == 11) { echo $phone . " is valid format."; } 

Выходной выход

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

 <?php // escape output sent to the browser echo "You searched for: " . htmlspecialchars($_GET["query"]); 

Все вместе сейчас!

Чтобы лучше понять три аспекта обработки данных, давайте еще раз посмотрим на систему комментариев на основе файлов из предыдущего и изменим ее, чтобы убедиться в ее безопасности. Потенциальные уязвимости в коде связаны с тем, что $_POST["comment"] слепо добавляется в файл comments.txt который затем отображается непосредственно для пользователя. Чтобы защитить его, значение $_POST["comment"] должно быть проверено и очищено перед его добавлением в файл, а содержимое файла должно быть экранировано при отображении для пользователя.

 <?php // validate comment $comment = trim($_POST["comment"]); if (empty($comment)) { exit("must provide a comment"); } // sanitize comment $comment = strip_tags($comment); // comment is now safe for storage file_put_contents("comments.txt", $comment, FILE_APPEND); // escape comments before display $comments = file_get_contents("comments.txt"); echo htmlspecialchars($comments); 

Сценарий сначала проверяет входящий комментарий, чтобы убедиться, что строка ненулевой длины предоставлена ​​пользователем. В конце концов, пустой комментарий не очень интересен.

Проверка данных должна происходить в четко определенном контексте. Это означает, что если я ожидаю целое число от пользователя, то я соответствующим образом проверяю его, преобразовывая данные в целое число и обрабатывая его как целое число. Если это приводит к неверным данным, просто отбросьте их и сообщите пользователю об этом.

Затем скрипт очищает комментарий, удаляя любые HTML-теги, которые он может содержать.

И, наконец, комментарии извлекаются, фильтруются и отображаются.

Обычно функции htmlspecialchars() достаточно для фильтрации вывода, предназначенного для просмотра в браузере. Однако если вы используете кодировку символов на своих веб-страницах, htmlentities() от ISO-8859-1 или UTF-8, тогда вы захотите использовать htmlentities() . Для получения дополнительной информации о двух функциях, прочитайте их соответствующие описания в официальной документации PHP.

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

Резюме

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

Изображение с помощью Inge Schepers / Shutterstock

И если вам понравилось читать этот пост, вы полюбите Learnable ; место, чтобы узнать новые навыки и приемы у мастеров. Участники получают мгновенный доступ ко всем электронным книгам SitePoint и интерактивным онлайн-курсам, таким как Jump Start PHP .

Комментарии к этой статье закрыты. Есть вопрос по PHP? Почему бы не спросить об этом на наших форумах ?