Межсайтовый скриптинг ( XSS ) — это тип уязвимости безопасности , которую можно обнаружить в некоторых веб-приложениях . XSS-атаки позволяют злоумышленникам внедрять клиентские сценарии в веб-страницы, просматриваемые другими пользователями. Уязвимость межсайтового сценария может быть использована злоумышленниками для обхода средств контроля доступа , таких как политика одного и того же происхождения . Во второй половине 2007 года XSSed зафиксировал 11 253 межсайтовые уязвимости, специфичные для сайта, по сравнению с 2 134 «традиционными» уязвимостями, зарегистрированными Symantec . [1] Эффекты XSS варьируются от незначительного неудобства до значительного риска для безопасности, в зависимости от конфиденциальности данных, обрабатываемых уязвимым сайтом, и характера любых мер по снижению безопасности, реализованных сетью владельца сайта .
OWASP считает термин «межсайтовый скриптинг» неправильным . Первоначально это была атака, которая использовалась для взлома данных на сайтах, но постепенно стала включать и другие формы атак с внедрением данных. [2]
Безопасность в Интернете зависит от множества механизмов, включая базовую концепцию доверия, известную как политика одного и того же происхождения . Это означает, что если контенту с одного сайта (например, https://mybank.example1.com ) предоставлено разрешение на доступ к ресурсам (например, файлам cookie и т. д.) в веб-браузере, то контенту с любого 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]
Методы инъекции могут сильно различаться; в некоторых случаях злоумышленнику может даже не потребоваться напрямую взаимодействовать с самой веб-функцией, чтобы воспользоваться такой дырой. Любые данные, полученные веб-приложением (по электронной почте, системные журналы, мгновенные сообщения и т. д.), которые могут контролироваться злоумышленником, могут стать вектором внедрения.
XSS-уязвимости изначально были обнаружены в приложениях, выполнявших всю обработку данных на стороне сервера. Пользовательский ввод (включая вектор XSS) будет отправлен на сервер, а затем отправлен обратно пользователю в виде веб-страницы. Потребность в улучшении пользовательского опыта привела к популярности приложений, в которых большая часть логики представления (возможно, написанной на JavaScript ) работала на стороне клиента и извлекала данные по требованию с сервера с помощью AJAX .
Поскольку код JavaScript также обрабатывал вводимые пользователем данные и отображал их в содержимом веб-страницы, начал появляться новый подкласс отраженных XSS-атак, который назывался межсайтовым скриптингом на основе DOM . При XSS-атаке на основе DOM вредоносные данные не затрагивают веб-сервер. Скорее, это отражается в коде JavaScript, полностью на стороне клиента. [15]
Примером XSS-уязвимости на основе DOM является ошибка, обнаруженная в 2011 году в ряде плагинов jQuery . [16] Стратегии предотвращения XSS-атак на основе DOM включают меры, очень похожие на традиционные стратегии предотвращения XSS, но реализованные в коде JavaScript и содержащиеся в веб-страницах (т. е. проверка ввода и экранирование). [17] Некоторые фреймворки JavaScript имеют встроенные средства противодействия этому и другим типам атак — например, AngularJS . [18]
Self-XSS — это форма XSS-уязвимости, которая использует социальную инженерию , чтобы обманом заставить жертву выполнить вредоносный код JavaScript в своем браузере. Хотя технически это не настоящая XSS-уязвимость, поскольку она основана на социальной инженерии пользователя для выполнения кода, а не на дефекте уязвимого веб-сайта, позволяющем злоумышленнику это сделать, она по-прежнему представляет те же риски, что и обычная XSS-уязвимость, если правильно исполнено. [19]
Мутировавший XSS происходит, когда злоумышленник внедряет что-то, что кажется безопасным, но переписывается и модифицируется браузером во время анализа разметки. Это чрезвычайно затрудняет обнаружение или очистку логики приложения веб-сайта. Примером является перебалансировка незакрытых кавычек или даже добавление кавычек к параметрам без кавычек в параметрах семейства шрифтов CSS.
Существует несколько схем экранирования, которые можно использовать в зависимости от того, где в документе 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 (поэтому он отображается как « очень большой» вместо «<b>очень </b> большой"). Остановить XSS-атаку при приеме HTML-ввода от пользователей в этой ситуации гораздо сложнее. Ненадежный ввод HTML должен быть пропущен через механизм очистки HTML , чтобы гарантировать, что он не содержит код XSS.
Многие проверки основаны на анализе (занесении в черный список) конкретных HTML-тегов, находящихся под угрозой, таких как тег iframe , ссылка и тег сценария.
У этого подхода есть несколько проблем: например, иногда могут быть опущены, казалось бы, безобидные теги, которые при правильном использовании все равно могут привести к XSS.
Другой популярный метод — исключить вводимые пользователем символы «and», однако это можно обойти, поскольку полезные данные можно скрыть с помощью обфускации .
Помимо фильтрации контента, широко используются и другие несовершенные методы борьбы с межсайтовым скриптингом. Одним из примеров является использование дополнительных мер безопасности при аутентификации пользователей на основе файлов 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] Расширение NoScript для Firefox позволяет пользователям выборочно разрешать использование сценариев на одной странице и запрещать использование других сценариев на той же странице. Например, могут быть разрешены сценарии с сайта example.com, а сценарии с сайта Advertisingagency.com, пытающиеся запуститься на той же странице, могут быть запрещены. [34]
Политика безопасности контента (CSP) позволяет HTML-документам отключать некоторые сценарии, оставляя другие включенными. [35] Браузер проверяет каждый скрипт на соответствие политике, прежде чем принять решение о его запуске. Пока политика разрешает только надежные сценарии и запрещает динамическую загрузку кода , браузер не будет запускать программы от ненадежных авторов независимо от структуры HTML-документа.
Современные политики CSP позволяют использовать одноразовые номера для пометки сценариев в HTML-документе как безопасных для запуска вместо того, чтобы полностью отделять политику от содержимого страницы. [36] [37] Пока доверенные одноразовые символы появляются только в заслуживающих доверия сценариях, браузер не будет запускать программы от ненадежных авторов. Некоторые крупные поставщики приложений сообщают об успешном развертывании политик на основе nonce. [38] [39]
Доверенные типы [40] изменяют веб-API , чтобы проверить, что значения отмечены как доверенные. Пока программы используют только надежные значения, злоумышленник, контролирующий строковое значение JavaScript , не может вызвать XSS. Доверенные типы предназначены для проверки синими командами .
Другой подход защиты заключается в использовании автоматизированных инструментов, которые удаляют вредоносный код XSS на веб-страницах. Эти инструменты используют методы статического анализа и/или сопоставления с образцом для выявления потенциально вредоносных кодов и защиты их с помощью таких методов, как экранирование. [41]
Если с помощью этого параметра установлен файл cookie SameSite=Strict
, он удаляется из всех запросов между источниками. Если он установлен с помощью SameSite=Lax
, он удаляется из всех не «безопасных» запросов между источниками (то есть запросов, отличных от GET, OPTIONS и TRACE, которые имеют семантику только для чтения). [42] Эта функция реализована в Google Chrome с версии 63 и Firefox с версии 60. [43]
16 января 2000 года следующие имена были предложены и обсуждались среди небольшой группы инженеров по безопасности Microsoft: [...] На следующий день был достигнут консенсус – Межсайтовый скриптинг.