2010-05-06 5 views
5

Я разрабатываю веб-приложение, где пользователи могут отвечать на записи в блоге. Это проблема безопасности, поскольку они могут отправлять опасные данные, которые будут переданы другим пользователям (и выполняются javascript).Предотвращение атаки XSS

Они не могут отформатировать отправленный текст. Нет «смелых», никаких цветов, ничего. Просто простой текст. я пришел с этим регулярным выражением, чтобы решить мою проблему: «. " "?"

[^\\w\\s.?!()] 

Так что все, что не является символ слова (Az, AZ, 0-9), а не пробел,," ! "," ("или") "будет заменен пустой строкой. Затем каждая квадратная метка будет заменена на: «& quot».

Я проверяю данные на лицевой стороне и проверяю их на своем сервере.

Можно ли каким-либо образом обойти это «решение»?

Мне интересно, как StackOverflow делает эту вещь? Здесь много форматирования, поэтому они должны хорошо с этим справиться.

+0

Какой у вас язык на стороне сервера? –

+0

Java. Я использую Servlets – Colby77

+0

Вы ничего не говорили о '<>', который, вероятно, является наиболее важными символами, используемыми в xss ... – rook

ответ

0

Передний конец можно обходить с помощью Fiddler, например, добавив информацию о форме. На задней стороне используйте кодировку html, например. <a> = & lt; a & gt;

Таким образом, текст будет отображаться как текст, а не элементы html.

1
  1. Не допускайте HTML-теги.
  2. Не выводить ничего, что пользователь вводил без предварительного вытеснения HTML. Это гораздо более важный момент! Сделайте это, и у вас никогда не будет проблемы с XSS.
  3. Предоставьте функцию предварительного просмотра, чтобы пользователи могли видеть, как это будет выглядеть перед публикацией.

Если вы должны разрешить HTML-теги, определите белый список и проверьте вход пользователя против него. Вы можете даже использовать регулярное выражение для этого.

Say вы позволяете <p>, <a href="..."> и <img src="...">:

  1. найти все, что в строке пользователя, который соответствует <\S[^>]*>
  2. для каждого матча, проверить его против <(p|a href="[^"]+"|img src="[^"]+")/?>|</(a|p)>
  3. , если он не подходит, что строгое регулярное выражение , выброси это.
  4. См. Пункт № 2 выше.
  5. Постарайтесь умышленно сломать систему. Попросите других попытаться сломать систему.
2

Я согласен с Томалаком и просто хочу добавить несколько пунктов.

  1. Не допускайте HTML-теги. Идея состоит в том, чтобы обработать пользовательский ввод как текст и символы html-escape перед их рендерингом. Используйте для этого проект OWASP's ESAPI. This page explains the various possible encodings, о котором вы должны знать.
  2. Если вам нужно разрешить HTML-теги, используйте библиотеку для фильтрации. НЕ записывайте собственное регулярное выражение; им трудно получить право. Используйте OWASP's Anti-Samy project - он был разработан специально для этого прецедента.
3

Если вы просто хотите простой текст , не волнуйтесь о фильтрации определенных html-тегов. Вы хотите, чтобы равноценный PHP htmlspecialchars(). Хороший способ использовать это print htmlspecialchars($var,ENT_QUOTES); Эта функция будет выполнять следующие кодировки:

'&' (ampersand) becomes '&amp;' 
'"' (double quote) becomes '&quot;' when ENT_NOQUOTES is not set. 
''' (single quote) becomes '&#039;' only when ENT_QUOTES is set. 
'<' (less than) becomes '&lt;' 
'>' (greater than) becomes '&gt;' 

Это решает проблему XSS на самом низком уровне, и вам не нужны сложные библиотеки/регулярное выражение, которое вы надеваете» (и, вероятно, небезопасно, когда вся сложность является врагом безопасности).

Удостоверьтесь, что ИСПЫТАТЬ ФИЛЬТР XSS, запустив free xss scanner.

1

Я бы рекомендовал прочитать the XSS Prevention Cheat Sheet, в котором содержится подробная информация об избежании атак XSS. По существу, то, что вам нужно фильтровать, зависит от контекста, в который он будет использоваться.

К примеру, в таком сценарии:

<body>...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...</body> 

Вам нужно сделать:

& --> &amp; 
< --> &lt; 
> --> &gt; 
" --> &quot; 
' --> &#x27;  &apos; is not recommended 
/--> &#x2F;  forward slash is included as it helps end an HTML entity 

Хотя в случае href="" примера вам нужно сделать urlescape:

«За исключением буквенно-цифровых символов, избегайте всех символов с ASCII-значениями менее 256 с помощью %HH. Включение ненадежных данных в данные: URL-адреса не должны быть разрешены, так как нет хорошего способа отключить атаки с экранированием, чтобы предотвратить выключение URL-адреса. Все атрибуты должны быть указаны. Необязательные атрибуты могут быть разбиты на множество символов, включая [пробел]% * +, - /; < =>^и |. Обратите внимание, что кодировка сущностей не имеет смысла в этом контексте.»

Хотя процитированная статья дает полный вердикт, надеюсь, есть достаточно информации, в этом ответе, чтобы вы начали.

0

Удалите все плохие последовательности символов первой, например, сверхдолгая UTF-8, Unicode недействительны.

Вы должны быть более четко ли < и > отбрасываются или превратились в лицо.

Вам также необходимы раздеться или кодировать двойную и одинарные кавычки, в противном случае злоумышленник может добавить внутреннее событие, в котором вы не ожидали, например. < Введите имя = «комментарий» значение = «Foo „onSomething = полезной нагрузки, а =“» >

Если вы действительно хотите, чтобы некоторое подмножество HTML, будьте осторожны, пытаясь разобрать его с регулярными выражениями, особенно те, которые вы придумайте, например браузеры окажут хитрые теги <a b=">"onMouseOver=alert(42)> просто отлично, если регулярное выражение может не совпадать. Ознакомьтесь с ранее упомянутым Anti-Samy.

Если вы позволяете HTML-теги, которые имеют href или src атрибуты, убедитесь, что они указывают на http(s): схем, а не javascript: из них.

Смежные вопросы