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

StackOverflow https://stackoverflow.com/questions/24723

  •  09-06-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

Не делайте этого с регулярными выражениями.Помните, вы защищаете не только от допустимого 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, поскольку она не будет соответствовать ничего, чтобы заменить.Это не строго белый список.

Я бы предложил специально созданный инструмент, например АнтиСами.Он работает, фактически анализируя HTML, а затем просматривая DOM и удаляя все, чего нет в настраиваемый белый список.Основное отличие заключается в возможности изящно обрабатывать некорректный 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();
}

Другие советы

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

< a alt="xss-инъекция" href="http://www.malicous.com/bad.php" >

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

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

<[^\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, дополнения, которое регулярно обновляется.

^(\s|\w|\d|<br>)*?$ 

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

^(\s|\w|\d|<br>|<ul>|<\ul>)*?$

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

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

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

и увидеть, как вещи, нуждающиеся в побеге, убегают, а затем использовать это.


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

(Вероятно, это довольно разумный совет для любого копирования/вставки)

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

Идея просто проанализировать его как HTML и сгенерировать новый HTML, вероятно, лучше.

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

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

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

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

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

enter image description here

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top