Лучшее регулярное выражение для ловли атаки XSS (межсайтовый скриптинг) (на Java)? - PullRequest
21 голосов
/ 24 августа 2008

Джефф действительно написал об этом в Очистить HTML . Но его пример на C #, и я на самом деле больше интересуюсь версией Java. У кого-нибудь есть лучшая версия для Java? Достаточно ли хорош его пример, чтобы просто конвертировать напрямую из C # в Java?

[Обновление] Я назначил награду за этот вопрос, потому что когда я задавал вопрос, он был не таким популярным, как сегодня (*). Что касается чего-либо, связанного с безопасностью, чем больше людей в него смотрит, тем лучше!

(*) На самом деле, я думаю, что это все еще в закрытой бета-версии

Ответы [ 9 ]

65 голосов
/ 11 февраля 2009

Не делайте этого с регулярными выражениями. Помните, что вы не защищаете только от правильного HTML; Вы защищаете от DOM, который создают веб-браузеры. Браузеры могут быть легко обмануты для создания действительного DOM из недействительного HTML.

Например, см. Этот список обфусцированных XSS-атак . Готовы ли вы приспособить регулярное выражение для предотвращения настоящей атаки на Yahoo и Hotmail на IE6 / 7/8?

<HTML><BODY>
<?xml:namespace prefix="t" ns="urn:schemas-microsoft-com:time">
<?import namespace="t" implementation="#default#time2">
<t:set attributeName="innerHTML" to="XSS&lt;SCRIPT DEFER&gt;alert(&quot;XSS&quot;)&lt;/SCRIPT&gt;">
</BODY></HTML>

Как насчет этой атаки, которая работает на IE6?

<TABLE BACKGROUND="javascript:alert('XSS')">

Как насчет атак, которые не перечислены на этом сайте? Проблема с подходом Джеффа состоит в том, что это не белый список, как утверждается. Как кто-то на этой странице умело отмечает:

Проблема в том, что HTML должен быть чистым. Есть случаи, когда Вы можете перейти на взломанный HTML, и это не будет соответствовать этому, в этом случае это будет вернуть взломанную строку html как не будет соответствовать ничего, чтобы заменить. это не только в белом списке.

Я бы предложил специальный инструмент, подобный AntiSamy . Он работает, фактически анализируя HTML, а затем обходя DOM и удаляя все, что не входит в белый список configurable . Основным отличием является способность изящно обрабатывать искаженный HTML.

Самое приятное то, что он фактически выполняет модульные тесты для всех XSS-атак на вышеуказанном сайте. Кроме того, что может быть проще, чем этот вызов API:

public String toSafeHtml(String html) throws ScanException, PolicyException {

    Policy policy = Policy.getInstance(POLICY_FILE);
    AntiSamy antiSamy = new AntiSamy();
    CleanResults cleanResults = antiSamy.scan(html, policy);
    return cleanResults.getCleanHTML().trim();
}
10 голосов
/ 26 августа 2008
4 голосов
/ 10 февраля 2009

Я не уверен, что использование регулярного выражения - лучший способ найти весь подозрительный код. Регулярные выражения довольно легко обмануть, когда имеешь дело с неработающим HTML. Например, регулярное выражение, указанное в ссылке HTML Sanitize, не сможет удалить все элементы «a», которые имеют атрибут между именем элемента и атрибутом «href»:

Более надежный способ удаления вредоносного кода - использовать XML-анализатор, который может обрабатывать все виды HTML-документов (Tidy, TagSoup и т. Д.), И выбирать элементы для удаления с помощью выражения XPath. Как только HTML-документ анализируется в DOM-документе, можно легко и безопасно найти элементы для восстановления. Это даже легко сделать с помощью XSLT.

3 голосов
/ 07 июня 2014

Я извлек из NoScript лучший анти-XSS аддон, вот его Regex: Работа безупречна:

<[^\w<>]*(?:[^<>"'\s]*:)?[^\w<>]*(?:\W*s\W*c\W*r\W*i\W*p\W*t|\W*f\W*o\W*r\W*m|\W*s\W*t\W*y\W*l\W*e|\W*s\W*v\W*g|\W*m\W*a\W*r\W*q\W*u\W*e\W*e|(?:\W*l\W*i\W*n\W*k|\W*o\W*b\W*j\W*e\W*c\W*t|\W*e\W*m\W*b\W*e\W*d|\W*a\W*p\W*p\W*l\W*e\W*t|\W*p\W*a\W*r\W*a\W*m|\W*i?\W*f\W*r\W*a\W*m\W*e|\W*b\W*a\W*s\W*e|\W*b\W*o\W*d\W*y|\W*m\W*e\W*t\W*a|\W*i\W*m\W*a?\W*g\W*e?|\W*v\W*i\W*d\W*e\W*o|\W*a\W*u\W*d\W*i\W*o|\W*b\W*i\W*n\W*d\W*i\W*n\W*g\W*s|\W*s\W*e\W*t|\W*i\W*s\W*i\W*n\W*d\W*e\W*x|\W*a\W*n\W*i\W*m\W*a\W*t\W*e)[^>\w])|(?:<\w[\s\S]*[\s\0\/]|['"])(?:formaction|style|background|src|lowsrc|ping|on(?:d(?:e(?:vice(?:(?:orienta|mo)tion|proximity|found|light)|livery(?:success|error)|activate)|r(?:ag(?:e(?:n(?:ter|d)|xit)|(?:gestur|leav)e|start|drop|over)?|op)|i(?:s(?:c(?:hargingtimechange|onnect(?:ing|ed))|abled)|aling)|ata(?:setc(?:omplete|hanged)|(?:availabl|chang)e|error)|urationchange|ownloading|blclick)|Moz(?:M(?:agnifyGesture(?:Update|Start)?|ouse(?:PixelScroll|Hittest))|S(?:wipeGesture(?:Update|Start|End)?|crolledAreaChanged)|(?:(?:Press)?TapGestur|BeforeResiz)e|EdgeUI(?:C(?:omplet|ancel)|Start)ed|RotateGesture(?:Update|Start)?|A(?:udioAvailable|fterPaint))|c(?:o(?:m(?:p(?:osition(?:update|start|end)|lete)|mand(?:update)?)|n(?:t(?:rolselect|extmenu)|nect(?:ing|ed))|py)|a(?:(?:llschang|ch)ed|nplay(?:through)?|rdstatechange)|h(?:(?:arging(?:time)?ch)?ange|ecking)|(?:fstate|ell)change|u(?:echange|t)|l(?:ick|ose))|m(?:o(?:z(?:pointerlock(?:change|error)|(?:orientation|time)change|fullscreen(?:change|error)|network(?:down|up)load)|use(?:(?:lea|mo)ve|o(?:ver|ut)|enter|wheel|down|up)|ve(?:start|end)?)|essage|ark)|s(?:t(?:a(?:t(?:uschanged|echange)|lled|rt)|k(?:sessione|comma)nd|op)|e(?:ek(?:complete|ing|ed)|(?:lec(?:tstar)?)?t|n(?:ding|t))|u(?:ccess|spend|bmit)|peech(?:start|end)|ound(?:start|end)|croll|how)|b(?:e(?:for(?:e(?:(?:scriptexecu|activa)te|u(?:nload|pdate)|p(?:aste|rint)|c(?:opy|ut)|editfocus)|deactivate)|gin(?:Event)?)|oun(?:dary|ce)|l(?:ocked|ur)|roadcast|usy)|a(?:n(?:imation(?:iteration|start|end)|tennastatechange)|fter(?:(?:scriptexecu|upda)te|print)|udio(?:process|start|end)|d(?:apteradded|dtrack)|ctivate|lerting|bort)|DOM(?:Node(?:Inserted(?:IntoDocument)?|Removed(?:FromDocument)?)|(?:CharacterData|Subtree)Modified|A(?:ttrModified|ctivate)|Focus(?:Out|In)|MouseScroll)|r(?:e(?:s(?:u(?:m(?:ing|e)|lt)|ize|et)|adystatechange|pea(?:tEven)?t|movetrack|trieving|ceived)|ow(?:s(?:inserted|delete)|e(?:nter|xit))|atechange)|p(?:op(?:up(?:hid(?:den|ing)|show(?:ing|n))|state)|a(?:ge(?:hide|show)|(?:st|us)e|int)|ro(?:pertychange|gress)|lay(?:ing)?)|t(?:ouch(?:(?:lea|mo)ve|en(?:ter|d)|cancel|start)|ime(?:update|out)|ransitionend|ext)|u(?:s(?:erproximity|sdreceived)|p(?:gradeneeded|dateready)|n(?:derflow|load))|f(?:o(?:rm(?:change|input)|cus(?:out|in)?)|i(?:lterchange|nish)|ailed)|l(?:o(?:ad(?:e(?:d(?:meta)?data|nd)|start)?|secapture)|evelchange|y)|g(?:amepad(?:(?:dis)?connected|button(?:down|up)|axismove)|et)|e(?:n(?:d(?:Event|ed)?|abled|ter)|rror(?:update)?|mptied|xit)|i(?:cc(?:cardlockerror|infochange)|n(?:coming|valid|put))|o(?:(?:(?:ff|n)lin|bsolet)e|verflow(?:changed)?|pen)|SVG(?:(?:Unl|L)oad|Resize|Scroll|Abort|Error|Zoom)|h(?:e(?:adphoneschange|l[dp])|ashchange|olding)|v(?:o(?:lum|ic)e|ersion)change|w(?:a(?:it|rn)ing|heel)|key(?:press|down|up)|(?:AppComman|Loa)d|no(?:update|match)|Request|zoom))[\s\0]*=

Тест: http://regex101.com/r/rV7zK8

Я думаю, что он блокирует 99% XSS, потому что он является частью NoScript, надстройки, которая регулярно обновляется

1 голос
/ 02 июня 2009
^(\s|\w|\d|<br>)*?$ 

Это будет проверять символы, цифры, пробелы, а также тег <br>. Если вы хотите больше риска, вы можете добавить больше тегов, таких как

^(\s|\w|\d|<br>|<ul>|<\ul>)*?$
0 голосов
/ 22 декабря 2018

Этот вопрос прекрасно иллюстрирует прекрасное применение изучения теории вычислений. Теория вычислений - это область, которая фокусируется на создании математических представлений компьютеров.

Одним из наиболее глубоких исследований в теории вычислений являются доказательства, иллюстрирующие взаимосвязи различных языков.

Некоторые языковые отношения, доказанные теоретиками вычислений, включают:

enter image description here

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

JavaScript, по крайней мере, не зависит от контекста, поэтому мы со стопроцентной уверенностью знаем, что разработка регулярного выражения (regex), способного перехватывать все XSS, является невозможной задачей.

0 голосов
/ 09 сентября 2014

Старая тема, но, возможно, это будет полезно для других пользователей. Для php: https://github.com/PHPIDS/ существует инструмент поддерживаемого уровня безопасности. Он основан на наборе регулярных выражений, которое вы можете найти здесь:

https://github.com/PHPIDS/PHPIDS/blob/master/lib/IDS/default_filter.xml

0 голосов
/ 11 февраля 2009

[\s\w\.]*. Если это не совпадает, у вас есть XSS. Может быть. Обратите внимание, что это выражение допускает только буквы, цифры и точки. Он избегает всех символов, даже полезных, из-за страха перед XSS. Как только вы позволите &, у вас есть заботы. И просто заменить все экземпляры & на &amp; недостаточно. Слишком сложно доверять: P. Очевидно, что это запретит много легитимного текста (Вы можете просто заменить все несоответствующие символы на! Или что-то в этом роде), но я думаю, это убьет XSS.

Вероятно, идея просто проанализировать его как html и создать новый html.

0 голосов
/ 26 августа 2008

Самая большая проблема с использованием кода Джеффса - это @, который в настоящее время недоступен.

Я бы просто взял "сырое" регулярное выражение из кода Джеффса, если бы он мне понадобился, и вставил его в

http://www.cis.upenn.edu/~matuszek/General/RegexTester/regex-tester.html

и увидишь, что вещи, требующие побега, спасутся, а затем воспользуйся им.


Имея в виду использование этого регулярного выражения, я лично убедился бы, что я точно понимаю, что я делаю, почему и каковы будут последствия, если мне не удастся, прежде чем что-либо копировать / вставлять, как другие ответы пытаются помочь вам .

(Это, вероятно, довольно хороший совет для любого копирования / вставки)

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