xenon
@xenon
Too drunk to fsck

Есть ли здесь реальная reflected XSS или это false positive (безопасно ли включать URL запроса в код страницы)?

Может быть написал сумбурно, но ниже дополнение, которое упрощает все до одной строчки PHP (если ли здесь XSS?):

<?php
echo($_SERVER["REQUEST_URI"]);
?>


Тестирую один сервер, есть у него такая интересная штука, при обращении к /path/script.php?t=1165 в ответе:
<input type="hidden" name="url" value="/path/script.php?t=1165">

А это - именно то, что мы в адресе ставим ведь! Делаем t=1165zzz, и в ответе эти zzz появляются. А дальше интересное.

$ curl -is 'https://example.com/path/script.php?t=1165"><script>alert(11111)</script>zzzzz'  | grep 11111
<input type="hidden" name="url" value="/path/script.php?t=1165"><script>alert(11111)</script>zzzzz">
<input type="hidden" name="url" value="/path/script.php?t=1165"><script>alert(11111)</script>zzzzz">

(аж два раза упоминается)

Что мы получили? Да это же вроде reflected cross-site scripting уязвимость! Можем заманить юзера на специальный URL (типа вот такого вот) и выполнить JS код в его контексте! украсть куки или послать запрос который он может только послать. Ура (вроде бы).

Но... пробую через httpie и хренушки.
http -pHb 'https://example.com/path/script.php?t=1165"><script>alert(11111)</script>zzzzz' | grep zzz
GET /path/script.php?t=1165%22%3E%3Cscript%3Ealert(11111)%3C/script%3Ezzzzz HTTP/1.1
<input type="hidden" name="url" value="/path/script.php?t=1165%22%3E%3Cscript%3Ealert(11111)%3C/script%3Ezzzzz">
<input type="hidden" name="url" value="/path/script.php?t=1165%22%3E%3Cscript%3Ealert(11111)%3C/script%3Ezzzzz">


Я специально указал, чтобы он мне выводил хидеры запроса, включая сам GET. И мы видим, что сайт-то тупой, он по прежнему просто отражает все, что мы ему послали, не проверяя этого. Беда в том, что клиент (httpie) умный и эскейпит все наши опасные кавычки и скобочки. И такая же фигня при попытке отправить из браузера. (слеш могу передать, но одинарные и двойные кавычки, больше-меньше - hex-кодируются во всякие t=1165zzzzz\%22\\%22\\\%22\\\\%22%3C%3E%27%27%27. Уязвимость только через curl удалось воспроизвести. (Может какие-то старые браузеры еще так же будут себя вести?)

Пробовал POSTом отправить это значение t, но отражается именно запрос, так что ничего, что мы вложили в t там нет.

Пока что наиболее близкое по теме нашел вот здесь:
https://security.stackexchange.com/questions/22567...

Адрес сервера давать не хочу, но любые идеи попробовать могу.

Вопрос 1: Можно ли это как-то обойти, обхитрить?
Вопрос 2: Это поведение веб-клиентов - "хороший тон" (кто-то кодирует кавычки в хекс, а кто-то нет) или RFC номер такой-то обязывает кодировать?
Вопрос 3: Если на 1 ответа нет, или ответ "нет", то значит ли это, что в веб разработке всегда можно безопасно включать URI запроса в ответе?

Дополнение
Дополню кое-что. Это наш сервер (у меня и так есть к нему доступ, но я проверяю его), и я сделал простой заведомо уязвимый скрипт:
<?php
echo($_SERVER["REQUEST_URI"]);
echo($_REQUEST["t"]);
?>


При запросе к /_xss-test.php?t=...<b>bold</b>... имеем:

/_xss-test.php?t=...%3Cb%3Ebold%3C/b%3E......bold...

Второй bold (который из t берется) - все-таки жирным пишется. То есть, хоть браузер и кодирует наш адрес, при запросе параметра он берется раскодированный, а вот при запросе REQUEST_URI - остается с "процентами"... . Ну и вложение JS кода через параметр t тоже получается (но не через REQUEST_URI).

И задача упрощается до - есть ли XSS уязвимость в скрипте вида:
<?php
echo($_SERVER["REQUEST_URI"]);
?>

Точно так же у меня получается от этого скрипта получить XSS через curl, но не через httpie или браузер.
  • Вопрос задан
  • 206 просмотров
Пригласить эксперта
Ответы на вопрос 2
На практике в современных браузерах этот вектор в XSS не эксплуатируется из-за URI энкода. Последними популярными браузерами где этот вектор был эксплуатируем были IE 6/7, они не URI-енкодили GET-параметры при редиректе. Однако вставка URI без HTML-енкода в любом случае является ошибкой, даже если не приводит к XSS, например по стандарту должен HTML-енкодиться символ &, который может присутствовать в урлах.
Ответ написан
xenon
@xenon Автор вопроса
Too drunk to fsck
Сам себе отвечу.
1. В том браузере, который (как у меня) кодирует скобки-кавычки - проэксплойтить эту уязвимость нельзя. Кодирование есть на стороне браузера.
2. Это "хороший тон", RFC3986, секция 2.2 https://datatracker.ietf.org/doc/html/rfc3986#sect... обязывает кодировать только некоторые другие символы:

If data for a URI component would conflict with a reserved character's purpose as a delimiter, then the conflicting data must be percent-encoded before the URI is formed.

reserved = gen-delims / sub-delims

gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"

sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="


Никакого другого требования кодировать я не нашел. То есть, curl, когда не кодирует двойные кавычки и угловые скобки - действует строго по RFC, а вот httpie или браузер - сами кодируют "лишние" символы, но они не обязаны делать это.

Ну и главное тут - это происходит на стороне клиента, следовательно: 1) на стороне клиента может быть что-то поломаное, работающее с ошибкой. Может быть какой-то новый (новорожденный) браузер с этими проблемами. Может быть старый очень браузер. Могут быть какие-то особые настройки, сочетания настроек и дополнений, из-за которых он не делает так. и 2) Браузер вполне может исполнять только требования RFC, но не более. Защищать дырявое приложение от XSS атак он не обязан.

3. Включать REQUEST_URI в ответ неправильно. Лучше так не делать. Но, тем не менее, есть такой тонкий и негарантированный слой защиты в популярных браузерах, который защищает от этого. Но никто не дает никаких гарантий, положиться на это нельзя.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы