![]() |
https://forum.antichat.xyz/attachmen...a744f5a897.png
Каждый второй отчёт на HackerOne с пометкой «Resolved» - это XSS. Не потому, что уязвимость сложная, а потому, что разработчики раз за разом недооценивают контексты, в которых пользовательский ввод попадает в DOM. Классический Код:
alert(1)Код:
htmlspecialcharsЗдесь я разберу все три типа XSS в веб-приложениях, не пересказывая OWASP-вики (в сотый раз переписывать спеку смысла нет), а через анализ конкретных HTTP-запросов, ответов сервера и поведения DOM. Покажу, как выглядит поиск XSS уязвимостей на реальном пентесте, какие event-handler'ы обходят сигнатурные WAF прямо сейчас и почему даже DOMPurify - золотой стандарт санитизации - оказался дырявым через Prototype Pollution (CVE-2024-45801, CVSS 7.3 HIGH). Три типа cross-site scripting через призму HTTP-запросов Русскоязычные материалы обычно описывают три типа XSS абстрактно: «отражённая возвращается в ответе», «хранимая сохраняется на сервере», «DOM-based работает в браузере». Формально верно, но для пентестера бесполезно - нужен разбор на уровне конкретных запросов и точек внедрения. Reflected XSS атака - от GET-параметра до исполнения Reflected XSS возникает, когда значение из запроса (GET-параметр, POST-поле, HTTP-заголовок) попадает в ответ сервера без обработки. Ключевое слово - «контекст вставки». Один и тот же ввод ведёт себя совершенно по-разному в зависимости от того, куда он приземляется в HTML. Допустим, на целевом сайте есть поиск: Код:
GET /search?q=testКод:
Результаты по запросу: testКод:
Код:
aaa"'<>{}Код:
<>Но чаще бывает иначе. Значение попадает внутрь атрибута: Код:
Код:
Код:
">Код:
">Третий контекст - JavaScript. Если ввод попадает в конструкцию Код:
var x = 'ВВОД';Код:
';alert(1)//https://forum.antichat.xyz/attachmen...6807662453.png По данным YesWeHack, reflected XSS чаще всего находят в формах поиска, формах логина и URL-путях. При эксплуатации reflected XSS атакующий формирует URL с пейлоадом и доставляет его жертве через фишинг. Если сессия на cookie без флага Код:
HttpOnlyКод:
fetchКод:
document.cookieStored XSS эксплуатация - персистентный вектор Stored XSS - самый опасный тип, потому что пейлоад сохраняется на сервере и срабатывает у каждого посетителя заражённой страницы. Внедрение вредоносного скрипта идёт через поля, которые ложатся в базу: комментарии, профили пользователей, тикеты поддержки, названия файлов. На практике stored XSS эксплуатация выглядит так. Атакующий находит поле, которое принимает ввод и отображает его другим пользователям. Закидывает туда тег с обработчиком события - например, Код:
Код:
onerrorОтдельный подвид - blind XSS. Пейлоад отправляется через форму обратной связи или тикет и срабатывает только в админке, когда сотрудник открывает заявку. Атакующий не видит результат сразу, поэтому использует внешний callback-сервер (Burp Collaborator или свой) для подтверждения срабатывания. Blind XSS особенно ценен на bug bounty - он поражает привилегированных пользователей и часто оценивается как high или critical. Я на одном проекте через blind XSS в тикете поддержки утянул сессию администратора - заявка провисела в очереди три дня, и всё это время пейлоад терпеливо ждал. DOM-based XSS - когда сервер ни при чём https://forum.antichat.xyz/attachmen...6807761753.png DOM-based XSS отличается тем, что серверный ответ может быть полностью безопасным - уязвимость кроется в клиентском JavaScript, который берёт данные из контролируемого источника (source) и вставляет их в опасный приёмник (sink). Типичные source: Код:
location.hashКод:
location.searchКод:
document.referrerКод:
window.nameКод:
postMessageКод:
innerHTMLКод:
outerHTMLКод:
document.writeКод:
eval()Код:
setTimeout()Код:
jQuery.html()Методика поиска DOM-based XSS сводится к двум шагам. Первый - найти sink в коде. В DevTools на вкладке Sources ищем Код:
innerHTMLКод:
evalКонкретный cross-site scripting пример: скрипт берёт значение из Код:
window.location.hashКод:
decodeURIComponentКод:
innerHTMLКод:
https://target.com/#В React-приложениях аналогичная проблема возникает при использовании Код:
dangerouslySetInnerHTMLКод:
bypassSecurityTrustHtmlПоиск XSS уязвимостей: пошаговая методология пентеста Требования к окружению: Burp Suite Community/Pro (актуальная версия), браузер с настроенным прокси (FoxyProxy или системный прокси на Код:
127.0.0.1:8080Код:
xss-payload-list.txtШаг первый - маппинг поверхности атаки. Проксирую весь трафик через Burp, прохожу по приложению, заполняю все формы, кликаю все ссылки. В Target > Site map вижу полную карту параметров. Каждый параметр, который отражается в ответе - потенциальная точка для reflected XSS. Каждый параметр, который сохраняется и отображается позже - кандидат на stored XSS. Шаг второй - ручная проверка контекста. Для каждого отражённого параметра отправляю в Repeater тестовую строку со спецсимволами: Код:
'"<>(){}Код:
<>Код:
'"Код:
" onfocus=alert(1) autofocus="Шаг третий - фаззинг event-handler'ов. Если стандартные Код:
onerrorКод:
onclickКод:
onloadКод:
onanimationendКод:
ontransitionendКод:
onscrollendКод:
onbeforematchШаг четвёртый - проверка DOM. Открываю DevTools > Sources, ищу по ключевым словам Код:
innerHTMLКод:
document.writeКод:
evalКод:
$.html(Шаг пятый - проверка stored XSS. Вставляю пейлоад в каждое поле, которое сохраняется: имя пользователя, биография, комментарий, имя файла при загрузке. Затем проверяю, как этот ввод отображается - в личном кабинете, в админке, в email-уведомлениях. Blind XSS проверяю через callback на Burp Collaborator: внедряю Код:
Обход XSS фильтров: от стандартных payload до многоступенчатой доставки Реальные приложения не стоят голыми перед пентестером. WAF, серверная фильтрация, CSP, санитизаторы - слои защиты, которые нужно обходить последовательно. Именно здесь начинается настоящий XSS пентест. 📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше Получить доступ просто — достаточно проявить активность на форуме Помимо экзотических event-handler'ов, по данным PortSwigger XSS Cheat Sheet, работают следующие подходы к обходу:
DOMPurify от Cure53 - стандартная библиотека для санитизации HTML на клиенте. Если приложение использует Код:
DOMPurify.sanitize(userInput)Уязвимость получила оценку CVSS 7.3 (HIGH) с вектором CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L. Затронуты версии DOMPurify до 2.5.4 и до 3.1.3. Два CWE описывают суть проблемы: CWE-1333 (Inefficient Regular Expression Complexity) - неэффективность проверки глубины вложенности HTML, и CWE-1321 (Improperly Controlled Modification of Object Prototype Attributes) - недостаточная защита от Prototype Pollution. Атака работает двумя путями. Первый - специально сконструированный HTML с глубокой вложенностью, который обходит depth-checker DOMPurify. Второй - Prototype Pollution: если атакующий может загрязнить прототип Код:
ObjectКод:
Number.isNaNКод:
sanitize()Патч оказался элегантным - в коде DOMPurify обернули Код:
Number.isNaNКод:
unapplyКод:
FORBID_TAGSКод:
ADD_TAGSДля пентестера вывод простой: при обнаружении DOMPurify на целевом приложении - проверяйте версию. Код:
console.log(DOMPurify.version)true } ; // После загрязнения прототипа DOMPurify.sanitize() пропускает вредоносный HTML [/CODE] Маппинг XSS на MITRE ATT&CK: от внедрения до импакта XSS уязвимость эксплуатация - это не Код:
alert(1)Initial Access - Exploit Public-Facing Application (T1190). Атакующий эксплуатирует XSS уязвимость веб-приложения для первичного внедрения кода в контекст браузера жертвы. Для reflected XSS нужна доставка URL жертве, для stored - достаточно дождаться посещения заражённой страницы. Execution - JavaScript (T1059.007). Внедрённый скрипт исполняется движком JavaScript браузера. Атакующий ограничен браузерной песочницей, но внутри неё может выполнять произвольный код. Credential Access - Steal Web Session Cookie (T1539). Классический угон сессии через XSS: скрипт читает Код:
document.cookieКод:
HttpOnlyCollection - Browser Session Hijacking (T1185). Атакующий использует украденную сессию для выполнения действий от имени жертвы: смена email, пароля, вывод данных. Defense Evasion - Command Obfuscation (T1027.010). Многоступенчатая доставка payload, base64-кодирование, загрузка строк через Код:
fetchImpact - External Defacement (T1491.002) и Transmitted Data Manipulation (T1565.002). Подмена контента страницы для фишинга или дефейса, модификация данных форм перед отправкой на сервер. Такой маппинг в отчёте превращает «XSS в поле поиска» в цепочку атаки с конкретным импактом, что серьёзно влияет на оценку severity при XSS пентесте. Без маппинга - «medium, ну XSS же». С маппингом - «high, потому что T1539 → T1185 → полный захват аккаунта администратора». Content Security Policy обход: что работает на практике CSP - последний рубеж обороны, который блокирует исполнение инлайн-скриптов даже при успешной HTML-инъекции. Строгая политика Код:
script-src 'self'Самые частые ошибки конфигурации: наличие Код:
'unsafe-inline'Код:
'unsafe-eval'Код:
eval()Код:
cdnjs.cloudflare.comПодход с Код:
nonceКод:
script-src 'nonce-R4nd0m'Код:
Порядок действий при аудите CSP: скопировать заголовок Код:
Content-Security-PolicyКод:
csp-evaluator.withgoogle.comВопрос к читателям При тестировании WAF-обхода на реальных целях я всё чаще тянусь к event-handler'ам из PortSwigger XSS Cheat Sheet, которые не попали в сигнатуры: Код:
onscrollsnapchangingКод:
onbeforeinputКод:
oncontentvisibilityautostatechangeКод:
|
| Время: 07:17 |