Client-Side Fundamental
  • Добро пожаловать
  • Глава 1 - Начало работы с XSS
    • Браузерная модель безопасности
    • Знакомимся с уязвимостью XSS
    • Более глубокое понимание XSS
    • Опасный псевдопротокол javascript
  • Глава 2 - Защита и Обход для XSS
    • Первая линия обороны от XSS - Sanitization
    • Вторая линия обороны от XSS - CSP (Content Security Policy)
    • Третья линия обороны против XSS - сокращение области воздействия
    • Последние методы защиты от XSS - Trusted Types и встроенный Sanitizer API
    • Обход защитных мер - Обычные способы обхода CSP
    • Обход защитных мер - Mutation XSS
    • Самая опасная XSS - Universal XSS
  • Глава 3 - Атаки без JavaScript
    • Кто сказал, что для атаки обязательно выполнять JavaScript?
    • Prototype Pollution - Эксплуатация цепочки прототипов
    • Может ли HTML влиять на JavaScript - Введение в DOM clobbering
    • Template Injection in Frontend - CSTI
    • CSS Injection - Атака с использованием только CSS (Часть 1)
    • CSS Injection - Атака с использованием только CSS (Часть 2)
    • Можно ли атаковать, используя только HTML
  • Глава 4 - Межсайтовые атаки
    • Same-origin Policy и Same-Site
    • Введение в Cross-Origin Resource Sharing (CORS)
    • Проблемы Cross-Origin безопасности
    • Cross-Site Request Forgery (CSRF)
    • Спаситель от CSRF - Same-site cookie
    • От same-site до главного site
    • Интересная и практичная Cookie Bomb
  • Глава 5 - Другие интересные темы
    • То, что вы видите, это не то, что вы получаете - Clickjacking
    • Эксплуатация MIME Sniffing
    • Атаки на цепочку поставок во фронтенде - Attacking Downstream from Upstream
    • Атаки на веб-фронтенд в Web3
    • Самая интересная атака на побочные каналы фронтенда - XSLeaks (Часть 1)
    • Самая интересная атака на побочные каналы фронтенда - XSLeaks (Часть 2)
Powered by GitBook
On this page
  • Способы выполнения JavaScript
  • XSS в различных сценариях и механизмах защиты
  • HTML Injection
  • Attribute Injection
  • JavaScript Injection
  • Заключение
  1. Глава 1 - Начало работы с XSS

Более глубокое понимание XSS

В предыдущей части мы говорили о том, что зачастую при атаках нужно адаптировать вредоносный код XSS для обеспечения эффективности в разных ситуациях. Например, если точка внедрения находится в innerHTML, использование <script>alert(1)</script> не даст никакого эффекта. Поэтому нам нужно немного глубже изучить XSS, чтобы знать, какие методы можно использовать для атак.

Изучение атак — это изучение защиты. Чтобы эффективно защищаться, мы должны знать, как атаковать.

Способы выполнения JavaScript

Получив контроль над HTML, вы можете выполнять JavaScript несколькими способами.

Самый распространенный способ - использовать тег <script>. Однако одним из его недостатков является то, что его легко идентифицирует веб-брандмауэр (Web Application Firewall, WAF). Другой недостаток заключается в том, что он не работает в контексте innerHTML, как упоминалось ранее.

Помимо <script>, мы также можем использовать другие теги в сочетании со встроенными обработчиками событий для выполнения кода. Например:

<img src="qweqwe" onerror="alert(1)">

Этот код загружает несуществующее изображение и использует событие `onerror` для выполнения кода.

На самом деле, многие люди (включая меня) используют `x` в качестве `src`, потому что его легко писать и запоминать. Обычно путь `x` не существует, но если он существует, `onerror` не сработает. Поэтому есть шутка, что вы можете разместить изображение с именем `x` в корневом каталоге сайта, и некоторые злоумышленники могут не обнаружить уязвимость XSS.

Помимо `onerror`, можно использовать любой обработчик событий. Например:

<button onclick="alert(1)">Click me, please</button>

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

Для более короткого кода можно использовать событие onload в svg:

<svg onload="alert(1)">

Немного дополнительной информации: в HTML кавычки (`"`) для значений атрибутов не обязательны. Если в вашем содержимом нет пробелов, вы можете их удалить без проблем. Даже пробелы между тегами и атрибутами можно заменить на `/`. Таким образом, код для svg можно написать так:

<svg/onload=alert(1)>

Для создания полезной нагрузки XSS не требуются пробелы или кавычки.

Часто используемые обработчики событий включают: 1. onerror 2. onload 3. onfocus 4. onblur 5. onanimationend 6. onclick 7. onmouseenter

Помимо этих обработчиков событий, начинающихся с "on", есть еще один способ выполнения кода, который могли видеть разработчики фронтенда:

<a href=javascript:void(0)>Link</a>

Это используется для того, чтобы элемент не реагировал на нажатие. Из этого примера мы видим, что для выполнения кода можно использовать href, например:

<a href=javascript:alert(1)>Link</a>

Подводя итог, существует несколько способов выполнения JavaScript в HTML:

1. Тег <script> 2. Обработчики событий в атрибутах (начинающиеся с on) 3. Псевдопротокол javascript:

Знание этих методов позволяет использовать их в разных ситуациях.

XSS в различных сценариях и механизмах защиты

Обычно места, куда можно внедрить вредоносный код, называются точками внедрения.

<div>  Hello, <span id="name"></span></div><script>  const qs = new URLSearchParams(window.location.search)  const name = qs.get('name')  document.querySelector('#name').innerHTML = name</script>

Точка внедрения находится в строке document.querySelector('#name').innerHTML = name.

Различные точки внедрения влияют на то, как можно проводить атаки и как от них защищаться. Давайте рассмотрим три разных сценария.

HTML Injection

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

<?php echo "Hello, <h1>" . $_GET['name'] . '</h1>';?>

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

Например, использование часто встречаемого кода <img src=qweqwe onerror=alert(1)> позволяет выполнить JavaScript.

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

Attribute Injection

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

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo</title>
</head>
<body>
    <div id="content"></div>
    <script>
        const qs = new URLSearchParams(window.location.search);
        const clazz = qs.get('clazz');
        document.querySelector('#content').innerHTML = `
            <div class="${clazz}">
                Demo
            </div>
        `;
    </script>
</body>
</html>

В этом случае использование ранее упомянутого кода <img src=qweqwe onerror=alert(1)> не сработает, потому что введенное значение будет обрабатывается как содержимое атрибута.

Чтобы выполнить XSS в этом сценарии, можно экранировать атрибут и закрыть тег, например: "><img src=qweqwe onerror=alert(1)>. Таким образом, весь HTML превратится в:

<div class=""><img src=qweqwe onerror=alert(1)>">Demo</div>

После экранирования атрибута можно вставлять нужные HTML-теги.

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

Например, используя код " tabindex=1 onfocus="alert(1)" x=", который вообще не содержит <>, HTML превратится в:

<div class="" tabindex=1 onfocus="alert(1)" x="">  Demo</div>

В отличие от добавления новых HTML-тегов, этот метод атаки использует событие onfocus исходного тега div для выполнения XSS. Поэтому при фильтрации, помимо <>, необходимо кодировать также символы ' и ".

Кроме того, именно поэтому следует избегать написания кода вроде:

document.querySelector('#content').innerHTML = `  <div class=${clazz}>Demo</div>

Вышеупомянутый атрибут не заключен в кавычки или апострофы, поэтому даже если мы думаем, что защитили его, закодировав <>"', злоумышленник все равно может добавлять другие атрибуты с помощью пробелов.

JavaScript Injection

Иногда пользовательский ввод отражается не только в HTML, но и в JavaScript-коде. Рассмотрим пример:

<script>const name = "<?php echo $_GET['name'] ?>";  alert(name);</script>

Глядя на этот фрагмент кода, можно подумать, что достаточно закодировать кавычки ("), чтобы злоумышленник не смог выйти из строки. Однако такой подход ошибочен. Злоумышленник может закрыть тег скрипта (</script>) и внедрять дальше другие теги.

Поэтому, как и в предыдущих случаях, нужно кодировать не только кавычки, но и символы <, >, '. Это предотвратит выход из строки.

Однако даже при этом стоит учитывать, что добавление пустой строки приведет к ошибке SyntaxError, так как браузер не сможет интерпретировать код как допустимый JavaScript.

Рассмотрим еще один пример:

<script>const name = `Hello,<?php echo $_GET['name'] ?>`;alert(name);</script>

В этом случае для внедрения кода можно использовать шаблонные строки и синтаксис ${alert(1)}. Хотя для фронтенд-разработчиков такой код выглядит подозрительно, не каждый инженер может его распознать. Возможно, этот код написал бэкенд-разработчик, который просто подумал: "Для многострочных строк нужен этот символ", не осознавая его значения и потенциальных опасностей.

Заключение

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

Однако гарантирует ли кодирование символов <>"' полную безопасность? Не всегда.

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

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

1. Тег <script> 2. Обработчики событий в атрибутах (всегда начинающиеся с "on") 3. Псевдопротокол javascript:

Если первый метод, например innerHTML = '<script>alert(1)</script>', не работает, если невозможно использовать обработчики событий и псевдопротокол javascript:, а точка внедрения - innerHTML = data, какие еще способы можно использовать для выполнения скриптов? Подумайте над этим.

PreviousЗнакомимся с уязвимостью XSSNextОпасный псевдопротокол javascript

Last updated 8 months ago

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

шпаргалке по XSS