UTF-8 символы, которые не являются уязвимостями XSS - PullRequest
5 голосов
/ 30 апреля 2009

Я смотрю на строки кодирования, чтобы предотвратить атаки XSS. Прямо сейчас мы хотим использовать подход белого списка, где любые символы вне этого белого списка будут закодированы. Прямо сейчас мы берем такие вещи, как '(' и выводим '('). Насколько мы можем судить, это предотвратит большинство XSS.

Проблема в том, что у нас много международных пользователей, и когда весь сайт на японском языке, кодирование становится основной проблемой пропускной способности. Можно ли с уверенностью сказать, что любой символ вне базового набора ASCII не является уязвимостью и его не нужно кодировать, или есть символы вне набора ASCII, которые еще нужно кодировать?

Ответы [ 2 ]

11 голосов
/ 30 апреля 2009

Может быть (намного) проще, если вы просто передадите кодировку htmlentities () / htmlspecialchars

echo htmlspecialchars($string,  ENT_QUOTES, 'utf-8');

Но если этого достаточно или нет, зависит от того, что вы печатаете (и где).

см. Также:
http://shiflett.org/blog/2005/dec/googles-xss-vulnerability
http://jimbojw.com/wiki/index.php?title=Sanitizing_user_input_against_XSS
http://www.erich -kachel.de /? P = 415 (на немецком языке. Если я найду что-то похожее на английском -> обновить) edit: хорошо, я думаю, вы можете понять главное, не владея немецким ;) Строка

javascript:eval(String.fromCharCode(97,108,101,114,116,40,39,88,83,83,39,41)) 
передает htmlentities () без изменений. Теперь рассмотрим что-то вроде
<a href="<?php echo htmlentities($_GET['homepage']); ?>"
, которое отправит
<a href="javascript:eval(String.fromCharCode(97,108,101,114,116,40,39,88,83,83,39,41))">
в браузер. И это сводится к
href="javascript:eval(\"alert('XSS')\")"
Хотя htmlentities () выполняет работу с содержимым элемента, это не очень хорошо для атрибутов.
5 голосов
/ 19 мая 2009

В общем, да, вы можете полагаться на все, что не является безопасным, но есть несколько очень важных предостережений, которые следует учитывать:

  1. Всегда убедитесь, что вы отправка клиенту помечена как UTF-8. Это значит иметь заголовок что явно говорит "Content-Type: текст / html; charset = utf-8 "на каждый одна страница , включая все ваши страницы ошибок, если какой-либо контент на эти страницы ошибок генерируются из пользовательский ввод. (Многие люди забывают проверить их страницу 404, и это страница содержит дословно не найденный URL)
  2. Всегда убедитесь, что то, что вы отправляете клиенту действующий UTF-8. Это значит, что ты не может просто пройти через байты, полученные от пользователя обратно пользователь снова. Вам нужно расшифровать байты как UTF-8, примените предупреждение XSS в кодировке html, а затем закодируйте их как UTF-8, как вы пишите их обратно вне.

Первое из этих двух предостережений заключается в том, чтобы не допустить, чтобы браузер клиента видел кучу вещей, в том числе заглавные буквы, и обратился к некоторому локальному многобайтовому набору символов. Этот локальный многобайтовый набор символов может иметь несколько способов указания вредных символов ascii, от которых вы не защититесь. В связи с этим некоторые старые версии некоторых браузеров - кашель , т. Е. кашель - немного переусердствовали при обнаружении страницы с UTF-7; это не открывает никаких возможностей XSS. Чтобы защититься от этого, вы можете убедиться, что вы html-кодируют любой исходящий знак «+»; это чрезмерная паранойя, когда вы генерируете правильные заголовки Content-Type, но спасет вас, когда какой-нибудь будущий человек переключит переключатель, который отключит ваши пользовательские заголовки. (Например, поместив плохо настроенный обратный прокси-сервер кэширования перед вашим приложением или сделав что-то для вставки дополнительного заголовка баннера - php не позволит вам установить какие-либо заголовки HTTP, если какой-либо вывод уже записан)

Вторым из них является то, что в UTF-8 можно указывать «слишком короткие» последовательности, которые, хотя и недопустимы в соответствии с текущими спецификациями, будут интерпретироваться старыми браузерами как символы ASCII. ( Посмотрите, что говорит Википедия ) Также возможно, что кто-то может вставить один плохой байт в запрос; если вы передадите этот пакет пользователю, это может привести к тому, что некоторые браузеры заменят и плохой байт, и один или несколько байтов после него на «?» или какой-то другой «не мог понять этого» персонажа. То есть один плохой байт может привести к тому, что некоторые хорошие байты также будут поглощены. Если вы внимательно посмотрите на то, что вы выводите, возможно, где-то есть место, где злоумышленник, который мог стереть один или два байта с выхода, мог бы сделать XSS. Декодирование ввода как UTF-8 с последующим перекодированием предотвращает этот вектор атаки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...