Что такое xss атака
Хранимые, отображаемые и DOM-based XSS: выявление и блокирование
Существует несколько видов XSS:
Хранимые. Вредоносный код сохраняется на сервере и загружается с него каждый раз, когда пользователи запрашивают отображение той или иной страницы. Чаще всего проявляются там, где пользовательский ввод не проходит фильтрацию и сохраняется на сервере: форумы, блоги, чаты, журналы сервера и т.д.
Отображаемые. Вредоносная строка является частью запроса жертвы к веб-сайту. Сайт принимает и вставляет эту вредоносную строку в отправляемый ответ обратно пользователю.
Например, при переходе пользователем по ссылке: http://example.com/q= на странице отобразится гиперссылка, при наведении на которую выполнится скрипт alert(‘XSS’). Но для этого необходимо каким-то образом (например, с использованием социальной инженерии) заставить пользователя ввести эту ссылку в адресной строке.
XSS в DOM-модели. Представляет собой вариант как хранимой, так и отображаемой XSS-атаки. В данном случае вредоносная строка не обрабатывается браузером жертвы, пока настоящий JavaScript веб-сайта не выполнится.
С разбором реальной атаки через XSS на сайт под управлением WordPress можно ознакомиться в статье: Атака на сайт с WordPress через JavaScript и XSS
Как работает XSS
Предположим, что мы разработали веб-приложение, содержащее следующий код:
Статья носит информационный характер. Не нарушайте законодательство.
Тег отвечает за загрузку картинки на страницу, и при указании адреса, откуда ее загружать, добавляется обработчик событий, который активируется в случае успеха или ошибки при загрузке. В данном случае при ошибке загрузки картинки с ресурса example.com сработает обработчик событий onerror, который запустит скрипт alert(‘XSS’). Вариаций использования обработчиков событий также довольно много: onload, onerror, onmouseover и т.д. Но помимо безопасной конструкции злоумышленник может написать скрипт, который будет передавать ему на удаленный сервер cookie всех пользователей, посетивших страницу.
Есть и так называемые «слепые» XSS (blind XSS) — это вариант хранимой XSS. Суть их работы заключается в том, что злоумышленник не сможет сразу увидеть результат, или результат работы пейлоада будет выводиться, например, на какой-то другой странице, вроде формы обратной связи или публикации отзывов с предварительной модерацией сообщений. Прислав в тексте сообщения скрипт, злоумышленник не увидит никакой реакции от веб-приложения, однако на стороне администратора или модератора сервиса скрипт отработает, вызвав написанную злоумышленником функцию. Если рассматривать данный вид атаки в контексте примера XSS с кражей cookie, то в таком случае администратор, ничего не успев понять, передаст их злоумышленнику.
Его можно доработать, чтобы он выполнился также и в других контекстах. Для этого нужно будет подстроиться под них:
Проверить эти параметры может помочь использование XSS-полиглотов, которые учитывают различные контексты, например:
Такой пейлоад должен выполниться в любом контексте, то есть его можно поместить в любой параметр и не беспокоиться о том, в какой участок кода он попадет.
Существует довольно много пейлоадов-полиглотов, их можно взять из SecLists или тут.
Еще один вариант обхода блокировки WAF – методы обфускации пейлоада. Например, используя URL-Encode стандартный пейлоад , можно превратить в %3Cscript%3Ealert%28XSS%29%3C%2Fscript%3E.
Для автоматизации поиска и эксплуатации XSS-уязвимостей существуют специальные инструменты (фреймворки), такие как XSSer или XSStrike, оба являются бесплатными.
XSSer
Cross Site «Scripter» (также известный как XSSer) – это автоматический фреймворк для обнаружения и эксплуатации XSS-уязвимостей в веб-приложениях. Содержит несколько опций для обхода определенных фильтров и специальные техники внедрения кода.
Ключевые особенности инструмента:
возможность создания изображений или видеофайлов с XSS-пейлоадом для дальнейшей загрузки в веб-приложение;
поиск для внедрения XSS с помощью Google Dorks запросов;
проверка наличия XSS-фильтров у целевого веб-приложения;
опция генерации пейлоада для попыток обхода систем WAF;
выявление Blind XSS.
Установка
Для установки инструмента можно воспользоваться deb-пакетом с официального сайта https://xsser.03c8.net/, либо на github скачать скрипт установки.
apt install python3-pycurl python3-bs4 python3-geoip python3-geoip2 python3-gi python3-cairocffi
git clone https://github.com/epsylon/xsser.git
python3 setup.py install
Использование
Использование ключей для составления запроса
Стандартная команда для проверки XSS выглядит так:
Опции для настройки запроса
Использование графического интерфейса
И сразу лайфхак: указывая параметры URL, data, payloads и т.д., их необходимо обязательно заключать в кавычки подобно написанию в консоли. В графическом интерфейсе, видимо, не подразумевалась данная функция по умолчанию.
Вариантов настройки запросов в графическом интерфейсе тоже 2, как и в консольном варианте:
обычный режим — пользователь сам выбирает параметры для составления запроса;
мастер запросов — интерактивное окно, в котором необходимо последовательно выбирать такие параметры, как: метод отправляемого запроса, URL проверяемого веб-приложения (один URL или список), метод генерации пейлоадов (конкретный или автоматическая генерация), необходима ли анонимизация отправки запросов такими средствами, как Tor и т.д.
При запуске графического интерфейса, как уже говорилось ранее, появится окно программы, где вводится URL для тестирования, указывается использование поисковой системы страниц с уязвимостями, краулер, а также Tor прокси для анонимизации. Остальные настройки будут производиться в соответствующих разделах:
Connection
Основной раздел составления запроса.
метод используемых запросов (GET или POST);
прокси, если необходимо;
изменение заголовков User-Agent, Cookie, Referer, Headers (добавление новых заголовков);
дополнительно можно указать параметры игнорирования заголовков параметром drop-cookie, следование за редиректами с помощью опции follow-redirects и HTTP аутентификацию.
Cheker
Проверка доступности хоста и настройка проверки Blind XSS.
Vectors
Позволяет вручную установить пейлоад для проверки или использовать автоматическую генерацию.
Anti-antiXSS
Использование параметров для попытки обхода некоторых WAF, а также анти-XSS фильтры некоторых браузеров. Последнее не имеет смысла, так как заявленые браузеры являются устаревшими и вряд ли не используются на текущий момент.
Bypasser
Содержит различные настройки обфускации пейлоадов для обхода прочих средств защиты.
Technique
Различные техники внедрения пейлоада.
Exploit
Специальные методы выполнения инъекций.
После указания всех параметров можно нажать на главном окне кнопку «Fly» для выполнения атаки или кнопку «Aim» для генерации консольной команды.
Тестирование
Проверка автоматической генерации пейлоадов
Набор пейлоадов, которые предлагает XSSer, находится в файле ./core/fuzzing/vectors.py и записан в виде JSON. Сам список имеет вид:
Если сравнивать с XSStrike, то у него было несколько наборов:
базовые теги (img, iframe и т.д.)
обработчики событий (onload, onerror, onmouseover и т.д.)
функции (например confirm()) и т.д.
В процессе генерации все эти наборы совмещались друг с другом и получался объемный список пейлоадов. Но в XSSer оказалось, что параметр —auto отвечает лишь за использование уже существующего словаря, который, разумеется, можно расширить.
Во время тестирования все применяемые пейлоады кодируются в URL-Encode, а результаты автоматически записываются в текущей папке в файл XSSreport.raw, если не указано иное.
Проверка поиска уязвимых сайтов для XSS средствами Google Dork
Данная функция позволяет инструменту проводить поиск уязвимых страниц в Интернете, используя GoogleDork-запросы. В процессе поиска XSSer будет искать страницы по указанным критериям и, если найдет, отправит пейлоад для проверки наличия XSS-уязвимости. В самом простом случае запрос может выглядеть так:
Сама задумка данной функции понятна — поиск уязвимых страниц с помощью продвинутого поискового движка, но из-за того, что при ее использовании атакуются сторонние ресурсы в Интернете, не совсем понятно, зачем она была добавлена.
XSStrike
XSStrike — это пакет обнаружения XSS, оснащенный четырьмя рукописными синтаксическими анализаторами, интеллектуальным генератором полезной нагрузки, мощным механизмом фаззинга и быстрым сканером. Он распознаёт ответ с помощью нескольких анализаторов и затем обрабатывает полезные данные, которые гарантированно будут работать с помощью контекстного анализа, интегрированного в механизм фаззинга.
технология взлома контекста;
интеллектуальная генерация пэйлоадов;
поддержка методов GET & POST;
поддержка файлов cookie;
пэйлоады ручной работы для фильтрации и WAF-уклонения;
скрытое обнаружение параметров.
Более подробно про XSStrike на русском можно прочитать здесь.
Тестирование обхода WAF. XSSer vs XSStrike
Здесь указан URL, параметры POST-запроса, использование заготовленного словаря с пейлоадами и задержка в 1 секунду между запросами.
При использовании XSSer со стандартным набором пейлоадов, Nemesida WAF Free заблокировал все атаки, за исключением направленных на старые версии браузеров (например, Internet Explorer 6). Также не были заблокированы запросы, не преставляющие собой реальную атаку, например:
Есть символы, используемые в атаках, но отдельно не являющиеся опасными. Их блокировка потенциально может привести к ложным срабатываниям. В Nemesida WAF Free мы разрабатываем качественные сигнатуры для снижения количества ложных срабатываний.
Попытки обхода средств защиты также не дали дополнительных результатов при применении любого из доступных в инструменте методов кодирования пейлоадов.
Дополнительно применялась мультикодировка —Cem:
В этом случае пейлоад будет по очереди закодирован сначала в String.FromCharCode () (Str), после чего полученная строка будет закодирована в шестнадцатиричный код (Hex). Кодировок можно добавлять и больше, но это будет прямо пропорционально влиять на скорость проверки.
Если сравнивать эффективность XSStrike и XSSer, то мы, скорре, отдадим предпочтение последнему. Хотя в XSStrike есть функция преобразования полезной нагрузки в base64:
Параметр —data отвечает за содержимое тела POST-запроса, —skip позволяет пропустить проверку перед применением пейлоадов, а -e устанавливает кодировку пейлоадов.
Проблемы сигнатурного анализа
Nemesida WAF Free (только сигнатурный анализ)
При использовании инструмента XSStrike все атаки на веб-приложение также были заблокированы, даже с учетом попыток обхода защиты по умолчанию.
Вывод
XSS являются крайне опасными уязвимостями, которые могут навредить, в первую очередь, пользователям. Поэтому предлагаем небольшой список рекомендаций для защиты от них:
Кодирование входных данных: с помощью библиотек OWASP Encoding Project, HTML Purifier, htmLawed, Anti-XSS Class и т.д.;
Регулярный ручной и автоматизированный анализ безопасности кода и тестирование на проникновение: с использованием как рассмотренных XSSer и XSStrike, так и с Wapiti, Nikto Web Scanner или Acunetux;
Использование Nemesida WAF (хотя бы Free версию);
И, наконец, регулярно устанавливать обновления (и, если серьезно заморочиться, использовать расширения, предотвращающие запуск XSS-сценариев на странице).
Nemesida WAF доступен в виде установочных пакетов для популярных Linux-систем: Debian, CentOS и Ubuntu. Быстрый стар для тех, кто уже познакомился с продуктом, занимает порядка 5-7 минут. Инструкция по установке доступна по ссылке.
Frontend Security: о чем вы хотели бы забыть, но не сможете
Какие атаки на клиентскую часть веб-ресурсов вы знаете? XSS, CSRF, HTTP Response Splitting, Clickjacking, CSHM, атаки на CORS, следствия других ошибок программистов? В среднем разработчик вспоминает не половину, и даже не треть. Разнообразие атак зависит только от фантазии и любопытства злоумышленников, и все они созданы, чтобы навредить вашим клиентам, а значит — и вам.
Татьяна Новикова — ex-пентестер с опытом в безопасности около четырех лет, а ныне Application Security Engineer. В команде ЦАРКА (Центр анализа и расследования кибератак) она занималась пентестом — полной проверкой веб-ресурсов на безопасность. В том числе команда работала с white-box, то есть с исходными кодами, и разбирала безопасность не только бэкенда, но и фронтенда. Сейчас Татьяна перешла в Beeline Казахстан и занимается обеспечением процессов безопасной разработки.
На основе своего опыта она выступила на конференции Frontend Conf Live 2020. В одной статье, конечно, невозможно покрыть все уязвимости и потенциальные опасности, поэтому сегодня будет самое актуальное и страшное из доклада — то, что может нанести максимальный ущерб.
Когда мы задумываемся о наличии уязвимостей в своих продуктах, важно помнить один момент: они могут быть даже в тех кусочках кода, которые не вызывают у вас подозрений. На протяжении трех последних лет статистика PTSecurity утверждает, что 9 из 10 веб-приложений в нашем интернете уязвимы к атакам client-side. Но это не значит, что одно приложение из десяти не уязвимо: скорее всего, уязвимость в нем просто еще не выявили. Мы поговорим сегодня о некоторых видах атак, с которыми может столкнуться каждый разработчик.
XSS (Cross-Site Scripting)
Начать, наверное, стоит с HTML инъекций. На первый взгляд они кажутся безобидными, но по факту могут привести к очень неприятным последствиям, особенно для рядовых пользователей, которые зашли на ваш веб-ресурс. Чаще всего обычный пользователь ресурса не имеет навыков в разработке и плохо представляет, как всё работает, и поэтому не может опознать HTML-инъекцию или атаку, которая идет на него. Форма ввода пароля, которая отрисована на странице, обычно вызывает у него доверие, а в адресную строку, где могла притаиться вредоносная нагрузка, он чаще всего не смотрит. А это прекрасная почва для социальных инженеров.
Инъекции в JavaScript распространены и интересны злоумышленникам еще больше.
Места для инъекций (даже в CSS их делают, но это экзотика)
Что же это за инъекции такие? Основная их задача заключается в том, чтобы выполнить зловредный js-код в браузере атакуемого, но в контексте вашего домена. Чтобы, понятное дело, получить данные вашего пользователя.
К сожалению, очень часто такие уязвимости эксплуатируются так называемыми script kiddie. Это люди, которые начинают изучать безопасность или хотят дешево и не прилагая особых усилий кого-то взломать — им прикольно или даже выгодно посмотреть, как работает уязвимость, для которой уже кем-то создан эксплойт (эксплойтом называют скрипт, который позволяет эксплуатировать уязвимости). Но довольно часто их действия не настолько обдуманы, как у настоящих хакеров, и навредить они могут просто потому, что не до конца продумали свою атаку.
Проект OWASP (Open Web Application Security Project) агрегирует огромное количество информации о том, как бороться с самыми разными уязвимостями, и какие куски кода могут привести к тому, что у вас появятся те или иные уязвимости. Его подпроект OWASP Top Ten — статистический топ уязвимостей, которые в веб-ресурсах появляются. XSS атаки уже много лет входят в топ-10.
В 2013 году они были на 3 месте, а в 2017 спустились на 7 позицию. Однако не стоит думать, что XSS атаки сдали свои позиции, нет. Скорее просто другие уязвимости набрали больше оборотов. К тому же это деление достаточно условное.
Виды XSS
Сегодня известно 3 вида XSS: Reflected (отраженные атаки), Stored (хранимые атаки) и атаки на DOM. Список на самом деле условный, и он может измениться. Например, атаки на DOM активно стали эксплуатироваться только в последнюю пятилетку, так что через пару лет могут появиться и другие атаки.
Все примеры XSS-атак можно посмотреть на сайте XSS-игры, которую разработал Google как раз для тренировки в поисках XSS-атак. Рекомендую поиграть в эту игру, состоящую всего из 6 уровней. На каждом из уровней нужно найти одну уязвимость, то есть понять, каким образом можно проинъектировать свою вредоносную нагрузку в чужую страницу, и научиться находить такие уязвимости самостоятельно.
Reflected XSS
В разной литературе отраженные атаки называют по-разному (например, моментальными XSS), но суть одна и та же: страница, к которой вы обращаетесь, возвращает пользователю фрагменты запроса.
Отраженные XSS неудобны для атакующего тем, что они требуют социальной инженерии. Надо каким-то образом уговорить пользователя, например, перейти по ссылке. В этой ссылке в качестве параметра GET-запроса будет идти кусочек JS, который и выполнится в контексте его браузера.
Stored XSS
Раз это хранимые XSS — значит, они где-то хранятся, и чаще всего это база данных бэкенда. Это могут быть сообщения на форуме, комментарии к записям, и по большому счету всё, что угодно — любое сохраняемое сообщение от пользователя. И здесь важно помнить: если при сохранении в БД программисты-бэкендеры обычно (будем оптимистами) думают о защите от SQL-инъекций, то о защите от XSS при записи в базу они задумываются гораздо реже, что, наверное, вполне логично.
Хранимые XSS для злоумышленника — это клондайк. Достаточно оставить, к примеру, комментарий с XSS, и код из него выполнится у любого человека, попавшего на эту страницу, в контексте его браузера.
В общем случае даже социальной инженерии не нужно. Достаточно убедиться, что на эту страницу люди заходят, и все посетители этой страницы таким образом отдадут злоумышленнику свои куки.
В XSS-игре на втором уровне приведен пример хранимой XSS — небольшой чат, данные которого сохраняются.
Этот пример весьма забавный: мы подсовываем в запросе битую ссылку на картинку и говорим: если произойдет ошибка, выполни алерт. Поскольку ссылка битая, ошибка, конечно, произойдет, и алерт выполнится. И это всё, что нужно злоумышленнику — его js-код уже отработал. А что он внутри себя сделает — отправит куда-то куки или что-то еще — это другой вопрос.
DOM-based XSS
Это атаки, которые пытаются манипулировать Document Object Model из JavaScript. Если хранимые и отраженные XSS попадают на сервер, то его защита (например, Web Application Firewall) может их распознать. Но здесь ситуация страшнее, потому что DOM-based XSS до сервера вообще не дойдет. Все изменения будут происходить исключительно на стороне клиента, в браузере. Поймать его на сервере крайне тяжело.
Пример кода, который может привести к DOM-based XSS:
Если злоумышленник будет знать, что у вас есть такой кусочек кода, то ему достаточно после символа # указать alert(document.cookie). После чего отработает eval, и тот код, который был указан после #, будет выполнен.
В XSS-игре это третий уровень. Изменяя DOM, мы можем менять картинку, которую нам демонстрируют. Точно также можно вызвать выполнение какого-либо JavaScript-кода либо по ошибке, либо по наведению клика мыши — не принципиально, главное, чтобы ваш код выполнился.
Другие атаки по поведению очень схожи с XSS. Какие-то эксплуатируют XSS, но не крадут куки пользователя, а делают что-то другое. Посмотрим несколько самых распространенных вариантов, что может сделать злоумышленник, если найдет у вас уязвимость.
Что хакер может сделать?
Украсть куки и токены
Первый самый очевидный вариант — это кража кук или токенов, которые вы передаете вместе с сессией вашего пользователя. Понятное дело, злоумышленник не будет вызывать алерты, потому что он их вызывал тогда, когда выяснял, есть ли какие-то уязвимости на вашем сайте.
Примерно такой запрос он захочет выполнить в контексте вашего домена:
Чтобы собрать куки и токены ваших пользователей, ему нужно где-то на своем домене либо на чужом взломанном домене разместить специальный скрипт — сниффер. Скрипт будет слушать все запросы от вашего сервера и отлавливать те, у которых в качестве параметра “c” что-то есть. Здесь приведен простой пример, но все снифферы ведут себя примерно одинаково. Они собирают куки со всех пользователей, в браузере которых по каким-либо причинам может отработать XSS.
Но это, на самом деле, далеко не все. Что еще может сделать злоумышленник, найдя уязвимость во фронтовой части ресурса?
Выполнить действия от имени пользователя
Можно не красть чужую сессию, потому что в контексте, например, современных веб-ресурсов это может быть бесполезно: защитные механизмы могут сорвать сценарий с кражей кук. Есть, к примеру, HttpOnly куки, которые как раз призваны защищать от атак на стороне клиента. Могут быть и другие, более сложные варианты: если сессия живет небольшое количество времени или защитные механизмы на бэкенде отлавливают информацию, пришел ли пользователь с той же сессией, но с другим фингерпринтом, или что-то подобное.
В этом случае злоумышленник может воспользоваться CSRF (Cross-Site Request Forgery). Несмотря на то, что и XSS, и CSRF начинаются со слов Cross-Site, по поведению эта атака имеет совсем другую логику. Но на HackerOne примеры использования CSRF встречаются в среднем раз в неделю.
Как происходит обычное нормальное стандартное взаимодействие между браузером и каким-либо сервером?
Браузер шлет GET-запрос — дай мне страничку.
Сервер отвечает страничкой, в которой есть форма авторизации.
Пользователь заполняет форму в браузере и отправляет POST-запрос. Хотя в интернете до сих пор, к сожалению, можно найти сайты, которые шлют авторизационные данные GET-запросом.
После того как POST-запрос ушел, на сервере проверяются данные пользователя, то есть валидность логина-пароля.
Дальше все возвращаемые ответы идут в сопровождении куки, которая подтверждает активную сессию. И так, пока браузер обменивается какой-то информацией с сервером.
Давайте допустим, что на нашем ресурсе есть уязвимость, приводящая к CSRF. А что произойдет, если наш пользователь зайдет на какой-то сервер, подвластный злоумышленнику? Который злодей либо взломал, либо это изначально вообще его веб-сервер, который он полностью контролирует.
Ничего не подозревающий пользователь, авторизованный на вашем сайте и владеющий активной сессией с куками, нажимает на ссылку на сайте атакующего. После этого формируется запрос на ваш сайт, то есть на сайт, у которого есть CSRF-уязвимость.
CSRF — Cross-site Request Forgery
Это пример с GET-запросом, но важно понимать, что с POST-запросом это отработает так же успешно, просто атака будет немного сложнее. Потому что надо будет отправлять параметры и каким-то образом смоделировать клик на стороне уязвимого сайта. Однако, это тоже можно сделать JavaScript’ом.
CSRF-атаку очень часто используют в совершенно неочевидных местах. В качестве примера можно привести реальный кейс из практики: на одном ресурсе для смены пароля не надо было вводить старый пароль, а достаточно было два раза ввести новый и нажать кнопку SUBMIT (тоже небезопасно, однако уязвимости действительно чаще всего эксплуатируются в связках).
Злоумышленники создали сайт, который точно должен был заинтересовать всех нужных клиентов. Одному из них этот сайт прорекламировали, он туда зашел и, естественно, кликнул на какую-то форму. В результате отправился запрос на атакуемый сайт, и пароль клиента поменялся на нужный злоумышленникам. Клиент поделился ссылкой на сайт со всеми своими коллегами, и у них также поменялись пароли на атакуемом сайте.
Один из классических примеров, как еще можно эксплуатировать CSRF:
Это очень утрированный и не реалистичный пример перевода денег в каком-либо онлайн-кошельке, однако сама схема атаки не особо сильно изменится, если передавать данные POST запросом, например.
Достаточно скрыть этот код за открытием какой-нибудь интересной для пользователя картинки, и атака отработает.
Еще один распространенный вариант — это смена e-mail адреса. Его можно поменять от имени пользователя, и он об этом не узнает. Но вот доступ к своему личному кабинету потеряет, как только прервет сессию. Никому в голову не придет каждую сессию перепроверять в личном кабинете, всё ли в порядке с его e-mail адресом.
Но это тоже еще не всё, что хакер может сделать.
Подделать поля, наложить фреймы
Эта атака связана с внедрением JavaScript-кода — так называемый clickjacking или кража кликов, когда злоумышленник подделывает какие-то поля или накладывает абсолютно прозрачные фреймы поверх фреймов на вашей странице. При клике на них выполняется не то действие, которое указано на вашей странице, а другое.
Подделка полей, наложение фреймов — clickjacking
Вы наверняка сталкивались с такими вещами, если смотрели кино на бесплатных пиратских площадках. Вы кликаете на PLAY, но открывается дополнительная вкладка, которая что-то рекламирует, и только второй клик уже отрабатывает реально на PLAY.
При этом Clickjacking довольно сложно поймать.
Хакер может даже получить исполнение кода
Этот пример довольно экзотический, хотя весьма оверкильный. Если вашим сайтом пользуются люди, которыми могут всерьез заинтересоваться злоумышленников, помните о такой возможности.
Это очень сложная комплексная атака, которая требует продуманного и запланированного подхода. Нужно использовать социальную инженерию, на сайте должна быть уязвимость, и всё должно корректно отрисоваться. Тем не менее, успешные эксплуатации были. Рассмотрим один из вариантов.
Суть атаки в добавлении желтого поля “Additional plugins are required to display all the media on this page”. Оно очень похоже на то, что выдает браузер, когда ему действительно не хватает каких-то плагинов. Проблема в том, что выдается это на территории веб-страницы, то есть окно накладывается поверх нее.
Был случай, когда злоумышленники, внедрив JavaScript-код, отрисовали аналогичное поле, и при клике на Install Missing Plugins с их сервера скачивался исполняемый файл. После его установки злоумышленник мог делать на компьютере жертвы всё что угодно.
Использовать фреймворки, причем для обеих сторон
У злоумышленников сейчас есть много инструментов для автоматизации самых разных процессов, в том числе и фреймворки, которые анализируют сайты и подсказывает, куда, как и где можно встроить код. Фреймворки могут полностью скопировать визуальное оформление страниц или проверить, к чему и какие действия на вашем сайте могут привести. Например, есть фреймворк Browser Exploitation Framework (BeEF), который регулярно обновляется.
Фреймворки для разработчиков, казалось бы нацелены на обеспечение базовой безопасности и помогают избежать банальных ошибок, но и на них нельзя полагаться до конца и рассчитывать, что все их конструкции безопасны. Это касается и фронтенда, и бэкенда.
Потому что практически в каждом фреймворке, вне зависимости от того, client-side это или server-side, есть какая-нибудь небезопасная конструкция. И на сайте каждого разработчика фреймворка напротив этой конструкции будет стоять либо жирный восклицательный знак, либо целая плашка с текстом: «Внимание, если вы будете это использовать, то ответственность за безопасность ваших клиентов лежит только на вас!»:
Почему это так? Потому что очень часто используются так называемый сырой HTML. Иногда это нужно для удобства разработчика — какие-то вещи очень тяжело написать, если не использовать все возможности HTML. Также те разработчики, кто не хочет разбираться с тонкостями и особенностями фреймворка, но имеют определенный опыт написания чистого HTML, предпочитают иной раз поставить директиву использования сырого кода вместо того, чтобы разобраться, как же сделать правильно.
Был случай, когда уязвимость в Vue-коде получилось найти только после чтения исходников. Выяснилось, что программисты использовали v-HTML и передавали туда данные с сервера, абсолютно никак их не обрабатывая.
Вот так это можно сделать на Vue:
Возьмем простую страничку, где есть поле «Добро пожаловать» и какая-то ссылка в HTML. В данном случае код записан прямо здесь, но в реальности он будет получен с сервера, onmouseover=alert(. ). Если сервер никаким образом этот текст не обработал, то, понятно, что вы его тоже получите в том же виде, и эта уязвимость обязательно отработает.
Для остальных фреймворков много примеров можно найти в интернете, или почитать документацию и понять, как это делается. А мы, тем временем, подходим к главному вопросу.
Как защищаться?
Санитизировать приходящие от пользователей и от бэкенда данные (все, вообще, совсем)
Очищайте и отфильтровывайте всё потенциально опасное во всех запросах, которые к вам приходят — и от бэкенда, и от клиента, и вообще откуда угодно.
Для того, чтобы привести все примеры, как отфильтровывать служебные последовательности, как их эскейпить, понадобится еще как минимум две таких статьи. Вместо этого вам важно узнать и понять, как это делает конкретно ваш инструмент. И перед написанием кода на всякий случай проверять, что вы всё это помните, не забываете и ни с чем не путаете.
Следить за подключаемыми библиотеками/уязвимостями в используемых фреймворках
В табличке приведены уязвимости, которые найдены в 2020 году, не обязательно прямо в самих фреймворках и библиотеках, но в каких-то их компонентах или в других популярных библиотеках, которые их используют.
Обратите внимание на уровень уязвимостей — встречается не только medium. Пентестеры знают, что фронтовые уязвимости относительно редко поднимаются выше medium. Но во всех четырех случаях были уязвимости high level — либо в самих библиотеках/фреймворках, либо в использующих их компонентах.
Ресурс snyk.io предлагает довольно неплохую базу уязвимостей с достаточно быстрой актуализацией — как только уязвимость заявили и выпустили патч, в этой базе появляется запись об этом. У них также есть неплохие блоги про всё, что связано с безопасностью фронтенда и не только.
А если мне кажется, что я защищен?
На все описанное выше кто-то может сказать, что он достаточно защищен, т.к., например? у него есть Web Application Firewall. Но, во-первых, мы уже видели пример уязвимости, с которой не сможет справиться WAF — это уже рассмотренный DOM-based XSS. А во-вторых — что такое Web Application Firewall? Это механизм, действующий на основе набора сигнатур (с использованием, возможно, какого-то машинного обучения), который получает запрос, смотрит на него и выявляет, по каким критериям этот запрос может быть подозрительным.
Проблема в том, что это вечная гонка между злоумышленником и защитными механизмами: злоумышленник придумывает атаку, а WAF выбирает из нее сигнатуры и блокирует все атаки со схожими сигнатурами. Злоумышленник снова придумывает новую атаку, чтобы обойти ограничение WAF.
Так они могут, как кошка с мышкой, бегать друг за другом постоянно. Эта война, скорее всего, никогда не прекратится, ведь вероятность того, что создадут WAF, который умеет блокировать абсолютно все вредоносные запросы, стремится к нулю, потому что человеческая фантазия безгранична.
Кроме того, с каждой новой появляющейся технологией появляются новые уязвимости.
Это так называемый Polyglot XSS — специальная нагрузка, которую злоумышленники используют для проверки того, используется ли на сайте WAF. Для этого какой-либо фрагмент этой нагрузки вставляется в запрос и проверяется, среагирует сайт или нет. Ещё два года назад ни один WAF эту нагрузку не блокировал. Сейчас какие-то уже умеют это делать, но всё еще не все. Да и таких “полиглотов” в интернете очень много.
Поэтому, хотя WAF — это, безусловно, очень хорошо, и он остановит большое количество массовых атак, но если человеку принципиально вас взломать, он всегда сможет это сделать.
Остается центральный вопрос — а что же делать со всем этим?
Правильно устанавливать заголовки безопасности
Пожалуй, самый мощный механизм, который должен быть в арсенале любого разработчика — это правильная работа с заголовками безопасности. Их разработано большое количество, за что в первую очередь большое спасибо Google Chrome. Но до сих пор не все заголовки безопасности активно используются, поэтому посмотрим на них поближе.
CSP (Content-Security-Policy)
Content-Security-Policy, пожалуй, самый важный из них. Он устанавливается в качестве HTTP header и говорит о том, откуда можно брать контент для выполнения на вашей странице. К примеру, если вы тянете JavaScript-файлы со своего собственного домена, то все ОК. Туда также можно прописать CDN, с которого вы подтягиваете какие-то скрипты или другие вещи.
Content-Security-Policy: default-src ‘self’ *.trusted.com
Из крутого — туда можно прописать report-uri. Report-uri хорош тем, что если вы его укажете в своей policy, то все попытки обойти CSP будут вам репортиться именно на этот адрес:
Content-Security-Policy: default-src ‘self’; report-uri
Там же можно указать и большое количество другой полезной информации: например, откуда можно выполнять скрипты, брать стили, подтягивать картинки, как работать с веб-сокетами и много чего еще. Как работают и как сконфигурировать доступные директивы, можно посмотреть здесь.
HSTS (Strict Transport Security)
Этот заголовок безопасности говорит, что если доступен сертификат безопасности, и если на этот сайт пришли по HTTPS, то все подзапросы, которые с него будут уходить, должны идти тоже по шифрованному соединению, да и в целом на сайт можно попасть только по https.
Важно помнить, что если у вас на сервере не настроен редирект, то пришедших по HTTP вы не редиректите автоматических на HTTPS — то есть работать эти заголовки просто не будут, они будут игнорироваться. Поэтому такой редирект обязан быть на вашем сайте.
Если у вас есть сертификат, то какой бы пользователь по какой бы ссылке ни пришел, ходить он должен только по защищенному соединению. Иначе появляются атаки типа Man-in-the-Middle, когда, например, какой-нибудь не очень добросовестный провайдер интернета будет вам добавлять на страницу такое дикое количество рекламы, что страницу за ней не будет видно.
SOP (Same origin policy)
Same origin policy говорит о том, к чему имеют доступ новые открываемые окна в контексте того же домена. В общем случае мы рассчитываем на то, что все скрипты, которые мы собираемся использовать на нашей странице, должны иметь одно и то же происхождение. Причем под origin здесь понимается целый триплет: это и схема, и хост (имя вашего ресурса), и порт, по которому идет обращение:
В SOP всегда имеет смысл прописать полный список доменов вместе со схемами и портами, которым вы полностью доверяете.
Заключение
В заключение несколько пунктов:
Следите за новостями безопасности, даже если вам кажется, что вас это не касается. Каждый день обнаруживаются новые уязвимости и всегда может всплыть что-то, что связано с используемыми вами технологиями. Буквально за полгода может измениться абсолютно все. Может найтись какая-то новая уязвимость, которую никто раньше никогда не эксплуатировал. Например, тот же CSRF можно было реализовать еще с 1992 года, но только недавно его начали активно использовать.
Знайте особенности используемых технологий. Особенно если вы используете какие-то небезопасные конструкции в своем фреймворке или библиотеке. Важно быть в курсе и при необходимости их каким-то образом дополнительно обрабатывать.
Никому не доверяйте. Не только пользователю доверять нельзя, это и так понятно. Но даже по отношению к своему собственному бэкенду нужно проявлять разумную осторожность, как мы видели в примерах выше.
Берегите своих пользователей. Постарайтесь не подставлять их лишний раз и не подвергать опасности.