Статья Предотвращение межсайтового скриптинга (XSS)

Это не оригинальная статья, а всего лишь перевод. Оригинал вот

1589992886331.png


Межсайтовый скриптинг является одной из наиболее распространенных и популярных веб-атак.

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

Последствия и воздействие могут варьироваться в зависимости от типа атаки и контекста, в котором она была запущена.

XSS можно классифицировать как:
  • Self-XSS / Reflected XSS / Non-persistent XSS / Type-II XSS
  • Persistent XSS / Stored XSS / Type-I XSS
  • DOM based XSS

Self-XSS

Предположим, что у нас есть следующий PHP-код - PHP просто для примеры:

PHP:
<?php
  $id = $_GET['id'];
  // ... пропусукаем ненмого кода :-)

  // простой пример Simple XSS :
  //   $_GET['id'] остался незаполненным
  //   и позже просто внедряется в HTML.
?>
<!DOCTYPE html>
<!-- Some more html -->
<script type="text/javascript">
  function getLink() {
    var link = "https://my-website.com/post.php?id=<?= $id; ?>";
  }
</script>
Пример Self-XSS

Учебник XSS: жертва открывает ссылку, которая выглядит так:

Код:
GET https://my-website.com/page.php?id=%22%3B%20alert(1)%3B%20var%20a%20%3D%20%22

(GET https://my-website.com/page.php?id=”; alert(1); var a = “)

и, волшебным образом, приведенный выше код, после преобразования в PHP будет отправлен в браузер жертв, и будет выглядеть уже так:

HTML:
<!--
  Создан запрос:
    GET https://my-website.com/page.php?id="; alert(1); var a = "
  Сгенерирован вывод
-->
<!DOCTYPE html>
<!-- Пропускаем html код -->
<script type="text/javascript">
  function getLink() {
    var link = "https://my-website.com/post.php?id=";
    alert(1);
    var a = "";
  }
</script>
Генерируемый вывод

В этом случае мы просто открываем всплывающее окно и отображаем внутри него "1", но злоумышленник может получить гораздо больше возможностей: он может сделать AJAX-звонок и отправить document.cookie на свой сервер (при условии, что приложение не установило флаг HTTP-Only для сессионных куки).

Это называется reflected XSS, так как вы посылаете вредоносный запрос и получаете вредоносный ответ обратно.

Имейте в виду: жертва должна будет открыть вредоносную ссылку (которая может быть сокращена с помощью сторонних сайтов).


Persistent XSS

Похож на Self-XSS, но другой рабочий процесс: $id в этом случае хранится в базе данных (или другом постоянном хранилище), а затем, считывается жертвой(ами).

Классическим примером здесь может служить платформа, позволяющая пользователям размещать контент, который затем отображается другим пользователям (т.е. Medium): злоумышленник сможет вписать в сообщение некоторое количество JS, а любой пользователь, прочитавший это сообщение, сможет автоматически запустить вредоносный JS-код.

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


DOM based XSS

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

HTML:
<HTML>
<TITLE>Welcome!</TITLE>
Hi
<SCRIPT>
var pos=document.URL.indexOf("name=")+5;
document.write(document.URL.substring(pos,document.URL.length));
</SCRIPT>
<BR>
Welcome to our system
…
</HTML>
Пример XSS на базе DOM

Обычно эта HTML-страница используется для приветствия пользователя:

GET [URL]http://my-website.example.com/welcome.html?name=Michele[/URL]

какой бы ни была просьба:

GET http://my-website.example.com/welcome.html?name=<script>alert(document.cookie)</script>

приведет к состоянию XSS.

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



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

Контекст - это фундаментальное слово в этом предложении, и именно поэтому XSS мало чем отличается от SQL или XML/HTML инъекций.


Что может сделать злоумышленник?

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

Ad-Jacking – Размещение рекламу, для заработка денег.

Click-Jacking - Создание скрытого overlay на странице для перехвата кликов жертвы с целью выполнения вредоносных действий.

Session Hijacking - Если флаг HTTP ONLY отсутствует в куки, то HTTP- куки могут быть доступны для JavaScript.

Content Spoofing - JavaScript имеет полный доступ к коду клиентской стороны веб-приложения и, следовательно, может использовать его для отображения/изменения содержимого.

Credential Harvesting - Может использовать фальшивое всплывающее окно для сбора учетных данных: Прошивка WiFi была обновлена, введите повторно свои учетные данные для аутентификации.

Forced Downloads - Значит, жертва не загружает свой вредоносный флеш-плеер с абсолютно безопасного сайта? Нет проблем: он может просто попытаться принудительно скачать с доверенного сайта, который посещает жертва.

Crypto Mining - Может использовать процессор жертвы для добычи биткоина (или альткоина).

Bypassing CSRF protection - Может собирать и отправлять CSRF токены для выполнения POST-операций в других местах сайта.

Keylogging – Отслеживает вводимые данные с клавиатуры.

Запись Аудио, Снимков и Гео-локаций - для этого требуется авторизация пользователя, но злоумышленник может получить доступ к камере, микрофону и местоположению жертвы. Благодаря HTML5 и JavaScript.

Воровство данных веб-хранилищаHTML5 - Веб-сайт может хранить данные в браузере для последующего использования и, конечно же, JavaScript может получить доступ к этому хранилищу через window.localStorage() и window.webStorage().

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

Network Scanning - Браузер жертвы может быть использован для сканирования портов и хостов с помощью Javascript.

Crashing Browsers - Закрытие браузеров - Почему нет?! :)

Воровство Информации - Ворует информацию с веб-страницы и отправляет ее на его вредоносный сервер.

Redirecting – Перенаправляет вас на сторонние источники

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

Capturing Screenshots - Благодаря HTML5 снова, можно сделать скриншот веб-страницы. Инструменты обнаружения Blind XSS делали это еще до того как это стало мейнстримом.

Perform Actions – Управление браузером.

Не все потеряно, межсайтовый скриптинг можно предотвратить!


Что возможно сделать?
  • использовать брандмауэр веб-приложений (он может блокировать некоторые самые распространенные атаки, но не все)
  • использовать , который останавливает загрузку страниц, когда браузер обнаруживает reflected межсайтовый скриптинг (устаревшая функция IE).
  • использовать заголовки , (и т.д.) для ограничения воздействия
Но опять же, ни одно из вышеперечисленного действия (или их комбинация) не является решением актуальной проблемы. Это может дать вам ложное ощущение безопасности.

Реальным решением является написание неуязвимого кода :) .

Как было сказано ранее:

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

Таким образом, решение заключается в корректном экранировании содержимого, в зависимости от контекста, в котором они живут: в общем HTML контексте <,> имеют специальные значения, поэтому они должны быть скрыты в коде (&lt;&gt); в HTML контексте атрибута, вместо этого, двойные кавычки (или одиночные кавычки) имеют специальное значение, поэтому они должны быть преобразованы в их эквиваленты HTML кода (&quot;), и т.д.....

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

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

Я попробую перечислить несколько языков.

Поскольку вас интересует безопасность и общие уязвимости, вы также можете почитать о


Стандартный - C# (ASP.NET)

, используемый в MVC, автоматически кодирует все выходные данные, исходящие из переменных. Вы также можете использовать JavaScriptEncoder для кодирования переменных в Javascript контексте.


Стандартный - Go (Golang)

экранирует специальные символы (<>&" ") в их HTML-код эквиваленты

предоставляет больше контроля и лучшую функциональность экранирования для CSS/JS/HTML.


Стандартная - Java

OWASP предоставляет AntiSamy (API для обеспечения соответствия HTML/CSS, поставляемого пользователем, правилам приложения).

OWASP также предоставляет Java-HTML-Sanitizer, который делает практически то же самое, но по-другому. HTML-Sanitizer быстрее и проще в использовании, но менее гибкий.

OWASP также использовали для обеспечения , но теперь это уже устаревший проект.


Стандартный - PHP

преобразует все применимые символы в сущности HTML, но это не лучший способ предотвратить XSS.

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


Стандартный - Python

позволяет вам конвертировать &<> (и " ' по запросу) в их эквиваленты HTML-кода.



Angular 2,3,4,5,6,7,8,9 — JS

По умолчанию Angular считает все значения ненадежными. Когда значение вставляется в DOM из шаблона, через свойство, атрибут, стиль, привязку к классу или интерполяцию, Angular «дезинфицирует» и экранирует недостоверные значения.


Django — Python

Если Вы используете шаблоны Django, вы защищены от большинства XSS-атак. Однако он не защищен от дураков: избегают , которые особенно опасны для HTML, но они не защитят вас, например, от атак, основанных на атрибутах HTML.


Flask — Python

Flask по умолчанию.


Laravel — PHP

В Laravel ≥5, по умолчанию {{ }} должны экранировать все выходные данные.


React — JS

React автоматически экранирует переменные, но есть несколько моментов. Подробнее об этом можно узнать .


Symfony — PHP




Подписывайтесь на Infosec Write-ups, чтобы получать больше таких статей.
 
Последнее редактирование:

z3r0c10wn

Grey Team
04.09.2017
229
295
BIT
200
А что вы скажите по поводу modsecurity в рамках этого вопроса - уважаемый. Мне кажется что кроссплатформенность данного решения позволяет решить множество проблем, и унифицировать детекты под необходимую платформу.
 
  • Нравится
Реакции: alik1c
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!