Межсайтовый скриптинг ( XSS ) [a] — это тип уязвимости безопасности , который можно найти в некоторых веб-приложениях . Атаки XSS позволяют злоумышленникам внедрять клиентские скрипты в веб-страницы, просматриваемые другими пользователями. Уязвимость межсайтового скриптинга может использоваться злоумышленниками для обхода контроля доступа, такого как политика одинакового происхождения . Во второй половине 2007 года XSSed задокументировал 11 253 уязвимости межсайтового типа, специфичные для сайта, по сравнению с 2 134 «традиционными» уязвимостями, задокументированными Symantec . [1] Эффекты XSS варьируются от незначительной неприятности до существенного риска безопасности, в зависимости от конфиденциальности данных, обрабатываемых уязвимым сайтом, и характера любых мер по снижению уровня безопасности, реализованных сетью владельца сайта .
OWASP считает термин «межсайтовый скриптинг» неверным . Первоначально это была атака, которая использовалась для взлома данных между сайтами, но постепенно она начала включать и другие формы атак с внедрением данных. [2]
Безопасность в Интернете зависит от множества механизмов, включая базовую концепцию доверия, известную как политика одного и того же источника . Она гласит, что если контенту с одного сайта (например, https://mybank.example1.com ) предоставлено разрешение на доступ к ресурсам (например, куки и т. д.) в веб-браузере, то контент с любого URL с той же (1) схемой URI (например, ftp , http или https), (2) именем хоста и (3) номером порта будет разделять эти разрешения. Контенту с URL, где любой из этих трех атрибутов отличается, необходимо будет предоставить разрешения отдельно. [3]
Атаки с использованием межсайтового скриптинга используют известные уязвимости в веб-приложениях , их серверах или подключаемых системах, на которые они полагаются. Используя одну из них, злоумышленники встраивают вредоносный контент в контент, доставляемый со скомпрометированного сайта. Когда полученный объединенный контент поступает в клиентский веб-браузер, он весь доставляется из доверенного источника и, таким образом, работает в соответствии с разрешениями, предоставленными этой системе. Найдя способы внедрения вредоносных скриптов в веб-страницы, злоумышленник может получить повышенные привилегии доступа к конфиденциальному контенту страницы, к файлам cookie сеанса и к различной другой информации, поддерживаемой браузером от имени пользователя. Атаки с использованием межсайтового скриптинга являются случаем внедрения кода .
Инженеры по безопасности Microsoft ввели термин «межсайтовый скриптинг» в январе 2000 года. [4] [ необходим неосновной источник ] Выражение «межсайтовый скриптинг» изначально относилось к действию загрузки атакуемого стороннего веб-приложения с не связанного с атакой сайта таким образом, что выполняется фрагмент JavaScript, подготовленный злоумышленником в контексте безопасности целевого домена (используя отраженную или непостоянную уязвимость XSS). Определение постепенно расширилось, чтобы охватить другие режимы внедрения кода, включая постоянные и не-JavaScript векторы (включая ActiveX , Java , VBScript , Flash или даже HTML- скрипты), что вызвало некоторую путаницу у новичков в области информационной безопасности . [5]
XSS-уязвимости были обнаружены и использованы с 1990-х годов. Известные сайты, пострадавшие в прошлом, включают сайты социальных сетей Twitter [6] и Facebook . [7] С тех пор уязвимости межсайтового скриптинга превзошли переполнения буфера и стали наиболее распространенной публично зарегистрированной уязвимостью безопасности, [8] некоторые исследователи в 2007 году оценили, что до 68% веб-сайтов, вероятно, открыты для XSS-атак. [9]
Не существует единой стандартизированной классификации уязвимостей межсайтового скриптинга, но большинство экспертов различают по крайней мере два основных типа уязвимостей XSS: непостоянные и постоянные . Некоторые источники далее делят эти две группы на традиционные (вызванные уязвимостями серверного кода) и основанные на DOM (в клиентском коде).
Непостоянная (или отраженная ) уязвимость межсайтового скриптинга на сегодняшний день является самым базовым типом веб-уязвимости. [10] Эти дыры появляются, когда данные, предоставленные веб-клиентом, [11] чаще всего в параметрах HTTP-запроса (например, отправка HTML - формы), немедленно используются серверными скриптами для анализа и отображения страницы результатов для этого пользователя без надлежащей очистки контента. [12]
Поскольку HTML-документы имеют плоскую, последовательную структуру, которая смешивает управляющие операторы, форматирование и фактическое содержимое, любые непроверенные пользовательские данные, включенные в результирующую страницу без надлежащего кодирования HTML, могут привести к внедрению разметки. [10] [12] Классическим примером потенциального вектора является поисковая система сайта: если кто-то ищет строку, строка поиска обычно будет дословно отображена на странице результатов, чтобы указать, что искалось. Если этот ответ не экранирует должным образом или не отклоняет управляющие символы HTML, возникнет ошибка межсайтового скриптинга. [13]
Отраженная атака обычно осуществляется по электронной почте или через нейтральный веб-сайт. Приманка — это невинно выглядящий URL, указывающий на доверенный сайт, но содержащий вектор XSS. Если доверенный сайт уязвим для вектора, нажатие на ссылку может заставить браузер жертвы выполнить внедренный скрипт.
Постоянная (или хранимая ) уязвимость XSS является более разрушительным вариантом уязвимости межсайтового скриптинга: она возникает, когда данные, предоставленные злоумышленником, сохраняются сервером, а затем постоянно отображаются на «нормальных» страницах, возвращаемых другим пользователям в ходе обычного просмотра, без надлежащего экранирования HTML. Классический пример этого — онлайн-доски объявлений, где пользователям разрешено размещать сообщения в формате HTML для прочтения другими пользователями. [ 12]
Например, предположим, что есть сайт знакомств, где участники просматривают профили других участников, чтобы увидеть, выглядят ли они интересными. Из соображений конфиденциальности этот сайт скрывает настоящие имена и адреса электронной почты всех участников. Они хранятся в секрете на сервере. Настоящее имя и адрес электронной почты участника отображаются в браузере только тогда, когда участник вошел в систему , и он не может видеть чужие.
Предположим, что Мэллори, злоумышленник, присоединяется к сайту и хочет выяснить настоящие имена людей, которых она видит на сайте. Для этого она пишет скрипт, предназначенный для запуска из браузеров других пользователей, когда они посещают ее профиль. Затем скрипт отправляет быстрое сообщение на ее собственный сервер, который собирает эту информацию.
Для этого на вопрос «Опишите свое идеальное первое свидание» Мэллори дает короткий ответ (чтобы казаться нормальным), но текст в конце ее ответа — это ее скрипт для кражи имен и адресов электронной почты. Если скрипт заключен в элемент <script>
, он не будет показан на экране. Затем предположим, что Боб, участник сайта знакомств, заходит на профиль Мэллори, в котором есть ее ответ на вопрос о первом свидании. Ее скрипт автоматически запускается браузером и крадет копию настоящего имени и адреса электронной почты Боба прямо с его собственного компьютера.
Постоянные уязвимости XSS могут быть более значительными, чем другие типы, поскольку вредоносный скрипт злоумышленника визуализируется автоматически, без необходимости индивидуально нацеливаться на жертв или заманивать их на сторонний веб-сайт. В частности, в случае сайтов социальных сетей, код будет дополнительно разработан для самораспространения по аккаунтам, создавая тип клиентского червя . [14]
Методы внедрения могут значительно различаться; в некоторых случаях злоумышленнику может даже не потребоваться непосредственное взаимодействие с веб-функционалом, чтобы использовать такую дыру. Любые данные, полученные веб-приложением (через электронную почту, системные журналы, IM и т. д.), которые могут контролироваться злоумышленником, могут стать вектором внедрения.
Уязвимости XSS изначально были обнаружены в приложениях, которые выполняли всю обработку данных на стороне сервера. Пользовательский ввод (включая вектор XSS) отправлялся на сервер, а затем возвращался пользователю в виде веб-страницы. Потребность в улучшенном пользовательском опыте привела к популярности приложений, в которых большая часть логики представления (возможно, написанной на JavaScript ) работала на стороне клиента, который извлекал данные по запросу с сервера с помощью AJAX .
Поскольку код JavaScript также обрабатывал пользовательский ввод и отображал его в содержимом веб-страницы, начал появляться новый подкласс отраженных XSS-атак, который назывался DOM -based cross-site scripting . В атаке XSS на основе DOM вредоносные данные не касаются веб-сервера. Вместо этого они отражаются кодом JavaScript, полностью на стороне клиента. [15]
Примером уязвимости XSS на основе DOM является ошибка, обнаруженная в 2011 году в ряде плагинов jQuery . [16] Стратегии предотвращения атак XSS на основе DOM включают в себя очень похожие меры на традиционные стратегии предотвращения XSS, но реализованные в коде JavaScript и содержащиеся в веб-страницах (т. е. проверка ввода и экранирование). [17] Некоторые фреймворки JavaScript имеют встроенные контрмеры против этого и других типов атак — например, AngularJS . [18]
Self-XSS — это форма уязвимости XSS, которая использует социальную инженерию , чтобы обмануть жертву и заставить ее выполнить вредоносный код JavaScript в своем браузере. Хотя технически это не настоящая уязвимость XSS, поскольку она использует социальную инженерию, заставляя пользователя выполнить код, а не уязвимость в уязвимом веб-сайте, позволяющую злоумышленнику сделать это, она по-прежнему представляет те же риски, что и обычная уязвимость XSS, если она реализована правильно. [19]
Mutated XSS происходит, когда злоумышленник внедряет что-то, что кажется безопасным, но переписывается и изменяется браузером при анализе разметки. Это делает его чрезвычайно сложным для обнаружения или очистки в логике приложения веб-сайта. Примером может служить перебалансировка незакрытых кавычек или даже добавление кавычек к незакрытым параметрам в параметрах CSS font-family.
Существует несколько схем экранирования, которые можно использовать в зависимости от того, где в HTML-документе необходимо разместить ненадежную строку, включая кодирование сущностей HTML, экранирование JavaScript, экранирование CSS и кодирование URL (или процентов) . [20] Большинство веб-приложений, которым не нужно принимать расширенные данные, могут использовать экранирование, чтобы в значительной степени устранить риск атак XSS довольно простым способом.
Выполнение кодирования HTML-сущностей только для пяти значимых символов XML не всегда достаточно для предотвращения многих форм атак XSS, библиотеки кодирования безопасности обычно проще в использовании. [20]
Некоторые системы веб-шаблонов понимают структуру HTML, которую они создают, и автоматически выбирают подходящий кодировщик. [21] [22] [23]
Многие операторы определенных веб-приложений (например, форумы и веб-почта) позволяют пользователям использовать ограниченное подмножество разметки HTML. При приеме ввода HTML от пользователей (например, <b>very</b> large
) выходная кодировка (например, <b>very</b> large
) будет недостаточной, поскольку ввод пользователя должен быть отображен как HTML браузером (поэтому он отображается как " very large", а не "<b>very</b> large"). Остановка атаки XSS при приеме ввода HTML от пользователей в этой ситуации гораздо сложнее. Недоверенный ввод HTML должен быть пропущен через механизм очистки HTML , чтобы гарантировать, что он не содержит кода XSS.
Многие проверки основаны на анализе (внесении в черный список) определенных «рискованных» HTML-тегов, таких как тег iframe , ссылка и тег script.
При таком подходе возникает несколько проблем, например, иногда могут быть упущены, казалось бы, безобидные теги, которые при правильном использовании все равно могут привести к XSS.
Другой популярный метод — убрать из пользовательского ввода символы « и », однако это также можно обойти, поскольку полезная нагрузка может быть скрыта с помощью обфускации .
Помимо фильтрации контента, также широко используются другие несовершенные методы смягчения последствий межсайтового скриптинга. Одним из примеров является использование дополнительных элементов управления безопасностью при обработке аутентификации пользователей на основе cookie . Многие веб-приложения используют сеансовые cookie для аутентификации между отдельными HTTP-запросами, и поскольку клиентские скрипты обычно имеют доступ к этим cookie, простые эксплойты XSS могут украсть эти cookie. [24] Чтобы смягчить эту конкретную угрозу (хотя и не проблему XSS в целом), многие веб-приложения привязывают сеансовые cookie к IP-адресу пользователя, который изначально вошел в систему, а затем разрешают этому IP использовать этот cookie. [25] Это эффективно в большинстве ситуаций (если злоумышленник ищет только cookie), но, очевидно, не работает в ситуациях, когда злоумышленник находится за тем же NAT -адресом IP или веб-прокси, что и жертва, или жертва меняет свой мобильный IP . [25]
Другим средством смягчения, присутствующим в Internet Explorer (начиная с версии 6), Firefox (начиная с версии 2.0.0.5), Safari (начиная с версии 4), Opera (начиная с версии 9.5) и Google Chrome , является флаг HttpOnly , который позволяет веб-серверу устанавливать cookie, недоступный для клиентских скриптов. Несмотря на свою полезность, эта функция не может ни полностью предотвратить кражу cookie, ни предотвратить атаки внутри браузера. [26]
В то время как разработчики Web 2.0 и Ajax требуют использования JavaScript, [27] некоторые веб-приложения написаны так, чтобы обеспечить работу без необходимости в каких-либо клиентских скриптах. [28] Это позволяет пользователям, если они захотят, отключать скрипты в своих браузерах перед использованием приложения. Таким образом, даже потенциально вредоносные клиентские скрипты могут быть вставлены на страницу без экранирования, и пользователи не будут подвержены атакам XSS.
Некоторые браузеры или плагины браузеров можно настроить на отключение клиентских скриптов на основе домена. Этот подход имеет ограниченную ценность, если скрипты разрешены по умолчанию, поскольку он блокирует плохие сайты только после того, как пользователь узнает, что они плохие, а это слишком поздно. Функциональность, которая блокирует все скрипты и внешние включения по умолчанию, а затем позволяет пользователю включать их на основе домена, более эффективна. Это было возможно в течение длительного времени в Internet Explorer (начиная с версии 4) путем настройки его так называемых «Зон безопасности», [29] и в Opera (начиная с версии 9) с помощью его «Настроек, специфичных для сайта». [30] Решением для Firefox и других браузеров на основе Gecko является дополнение NoScript с открытым исходным кодом , которое, в дополнение к возможности включения скриптов на основе домена, обеспечивает некоторую защиту от XSS, даже когда скрипты включены. [31]
Самая значительная проблема с блокировкой всех скриптов на всех веб-сайтах по умолчанию — это существенное снижение функциональности и скорости реагирования (скрипты на стороне клиента могут быть намного быстрее, чем скрипты на стороне сервера, поскольку им не нужно подключаться к удаленному серверу, а страницу или фрейм не нужно перезагружать). [32] Другая проблема с блокировкой скриптов заключается в том, что многие пользователи не понимают этого и не знают, как правильно защитить свои браузеры. Еще один недостаток заключается в том, что многие сайты не работают без скриптов на стороне клиента, что вынуждает пользователей отключать защиту для этого сайта и делает их системы уязвимыми. [33] Расширение Firefox NoScript позволяет пользователям выборочно разрешать скрипты с определенной страницы, запрещая другие на той же странице. Например, скрипты с example.com могут быть разрешены, в то время как скрипты с advertisingagency.com, которые пытаются запуститься на той же странице, могут быть запрещены. [34]
Политика безопасности контента (CSP) позволяет HTML-документам отключать некоторые скрипты, оставляя другие включенными. [35] Браузер проверяет каждый скрипт на соответствие политике, прежде чем решить, запускать ли его. Пока политика разрешает только надежные скрипты и запрещает динамическую загрузку кода , браузер не будет запускать программы от ненадежных авторов независимо от структуры HTML-документа.
Современные политики CSP позволяют использовать одноразовые номера для маркировки скриптов в HTML-документе как безопасных для запуска вместо того, чтобы полностью отделить политику от содержимого страницы. [36] [37] Пока доверенные одноразовые номера появляются только в заслуживающих доверия скриптах, браузер не будет запускать программы от ненадежных авторов. Некоторые крупные поставщики приложений сообщают об успешном развертывании политик на основе одноразовых номеров. [38] [39]
Доверенные типы [40] изменяют веб-API для проверки того, что значения были зарегистрированы как доверенные. Пока программы регистрируют только доверенные значения, злоумышленник, контролирующий строковое значение JavaScript, не может вызвать XSS. Доверенные типы разработаны для аудита синими командами .
Другой подход к защите заключается в использовании автоматизированных инструментов, которые удаляют вредоносный код XSS на веб-страницах. Эти инструменты используют методы статического анализа и/или сопоставления с образцом для выявления потенциально вредоносных кодов и защищают их с помощью таких методов, как экранирование. [41]
Когда cookie устанавливается с SameSite=Strict
параметром , он удаляется из всех запросов кросс-источника. Когда устанавливается с SameSite=Lax
, он удаляется из всех не-"безопасных" запросов кросс-источника (то есть запросов, отличных от GET, OPTIONS и TRACE, которые имеют семантику только для чтения). [42] Функция реализована в Google Chrome с версии 63 и Firefox с версии 60. [43]
января 2000 г. были предложены и обсуждены в небольшой группе инженеров по безопасности Microsoft следующие названия: [...] На следующий день был достигнут консенсус — Cross Site Scripting.