2013-11-21 3 views
3

Мы сталкиваемся с проблемами в нашей производственной среде с 100% -ным использованием ЦП и дампом нитей показывает, что наша реализация «черного списка» застряла в следующем.Регулярное выражение Высокий центральный процессор

[11/14/13 10:12:42:745 CST] 0000000d ThreadMonitor W WSVR0605W: Thread "Thread-002" (0000003b) has been active for 604063 milliseconds and may be hung. There is/are 1 thread(s) in total in the server that may be hung. 
    at java.lang.Character.isLetterOrDigit(Character.java:3516) 
    at java.util.regex.Pattern$Bound.check(Pattern.java:4820) 
    at java.util.regex.Pattern$Bound.match(Pattern.java:4832) 
    at java.util.regex.Pattern$Curly.match0(Pattern.java:3782) 
    at java.util.regex.Pattern$Curly.match(Pattern.java:3744) 
    at java.util.regex.Pattern$BmpCharProperty.match(Pattern.java:3366) 
    at java.util.regex.Pattern$Curly.match0(Pattern.java:3782) 
    at java.util.regex.Pattern$Curly.match(Pattern.java:3744) 
    at java.util.regex.Matcher.match(Matcher.java:1127) 
    at java.util.regex.Matcher.matches(Matcher.java:502) 

Проблема заключается в это не происходит всегда, которая означает, что она зависит от данных, и мы имеем следующий список регулярных выражений в нашей реализации Черного списка.

Я был бы признателен, если кто-то может сказать, какое регулярное выражение из следующего может потенциально вызвать 100% -ный CPU (я бы предположил из-за отслеживания обратной связи).

# zero/null bytes 
.*\x00.* 

# javascript 
.*\bjavascript\b.* &&! ^[\w.,;/*+= -]*\b(:?application/x-javascript|text/javascript)\b[\w.,;/*+= -]*$ 
# vbscript 
.*\bvbscript\b.* 

# <script or </script> 
.*<\s*/?\s*script\b.*|.*\bscript\s*>.* 
# <img or </img> 
.*<\s*/?\s*img\b.*|.*\bimg\s*>.* 
# <div or </div> 
.*<\s*/?\s*div\b.*|.*\bdiv\s*>.* 
# <html or </html> 
.*<\s*/?\s*html\b.*|.*\bhtml\s*>.* 
# <body or </body> 
.*<\s*/?\s*body\b.*|.*\bbody\s*>.* 
# <link or </link> 
.*<\s*/?\s*link\b.*|.*\blink\s*>.* &&! ^<\?xml .*$ 
# <meta or </meta> 
.*<\s*/?\s*meta\b.*|.*\bmeta\s*>.* 
# <base or </base> 
.*<\s*/?\s*base\b.*|.*\bbase\s*>.* 
# <span or </span> 
.*<\s*/?\s*span\b.*|.*\bspan\s*>.* 
# <input or </input> 
.*<\s*/?\s*input\b.*|.*\binput\s*>.* 
# <style or </style> 
.*<\s*/?\s*style\b.*|.*\bstyle\s*>.* 
# <table or </table> 
.*<\s*/?\s*table\b.*|.*\btable\s*>.* 
# <embed or </embed> 
.*<\s*/?\s*embed\b.*|.*\bembed\s*>.* 
# <frame or </frame> 
.*<\s*/?\s*frame\b.*|.*\bframe\s*>.* 
# <iframe or </iframe> 
.*<\s*/?\s*iframe\b.*|.*\biframe\s*>.* 
# <object or </object> 
.*<\s*/?\s*object\b.*|.*\bobject\s*>.* 

# <onload=> 
.*<.+\bonload\s*=.+>.* 
# <onerror=> 
.*<.+\bonerror\s*=.+>.* 
# <onmouseover=> 
.*<.+\bonmouseover\s*=.+>.* 
# <src=> 
.*<.+\bsrc\s*=.+>.* 
# <href=> 
.*<.+\bhref\s*=.+>.* 
# <style=> 
.*<.+\bstyle\s*=.+>.* 
# <content=> 
.*<.+\bcontent\s*=.+>.* 

# document. 
.*\bdocument\s*\..+ 
# element. 
.*\belement\s*\..+ 

# url(
.*\burl\s*\(.+ 
# eval(
.*\beval\s*\(.+ 
# alert(
.*\balert\s*\(.+ 

# /* */ 
.*/\*.*\*/.* 


# HTTP response splitting 
.*\bHTTP/\d+\.\d+.+ 


# Path traversal 
#.*\.\.[/\\].* 
.*\.\.[/\\]\.\.[/\\].* 


# SQL injection (probably not very useful) 

# from HttpServletBase.java 
.*select\s+\S*\s*from\s+\S+(?:\s+where\s+.+)?.* 
.*insert\s+\S*\s*into\s+\S+(?:\s+values\s+.+)?.* 
.*update\s+\S*\s*set\s+\S+(?:\s+where\s+.+)?.* 
.*delete\s+\S*\s*from\s+\S+(?:\s+where\s+.+)?.* 
+0

Как вы используете эти регулярные выражения? Вы можете сэкономить много CPU, повторно используя объекты Pattern. –

+0

Да, мы прекомпилируем их. Проблема, по-видимому, основана на некоторых данных, которые поступают на 100% -ный процессор, израсходована, это происходит не всегда, поэтому, чтобы найти какую-то помощь, чтобы определить, когда Regex может вызывать проблемы, например. backtracking и т. д. – user3017924

+1

Мой аргумент о производительности - это то, что вы единственный, кто может знать, что медленное. Найдите несколько образцов данных, которые показывают проблему, помещают их в своеобразный модульный тест, затем активируют/дезактивируют некоторое регулярное выражение, чтобы увидеть, какие из них проблематичны. –

ответ

1

Как я уже говорил в комментариях, собственно тестирование данных является единственным способом, чтобы действительно знать, какие регулярное выражение является проблематичным. Но я думаю, что есть что-то, что я могу определить, и вы можете заглянуть в нее. В принципе, будьте осторожны с оператором точек.

Посмотрите:

.*<.+\bonload\s*=.+>.* 

Я предполагаю, что вы хотите, чтобы найти какой-либо HTML тег, который содержит "OnLoad". Дело в том, что если у вас есть данные с большим количеством тегов, и никто не содержат «OnLoad», он будет делать так:

  1. Найдите первый <
  2. Пройдите до конца строки, чтобы найти " \ bonload "
  3. Поскольку ни одна из них не найдена, откат и попробуйте со следующим < в строке.

Это будет поэтому повторяться для каждого тега в строке, так что шаг 2 может быть дорогим, если ваша строка длинная. Вы можете оптимизировать, не допуская, чтобы он прошел мимо конца тега, заменив .+ на [^>]+ (то есть ничего, кроме >).

Таким образом, следующее регулярное выражение должно работать лучше:

.*<[^>]+\bonload\s*=.+>.* 

Кроме того, в соответствии с общим принципом, что «самый быстрый код код, который не работает», вы можете посмотреть, если строка содержит строку " onload "с простым поиском строк перед использованием регулярного выражения.

+0

Спасибо, что оказалось, что один из параметров содержал XML, у которого было много «<" ">», а XML был достаточно большим, а обратное отслеживание заставило CPU работать высоко. Спасибо. – user3017924

0

Возможно, я ошибаюсь, но регулярное выражение не спасет вас от атак XSS, поскольку они могут быть очень сложными: XSS Filter Evasion Cheat Sheet. Возможно, вам стоит взглянуть на OWASP's HTML sanitizer.

Для аналогичной проблемы в моем проекте я пришел с решением, которое объединило JSoup для анализа HTML и регулярных выражений, чтобы соответствовать строкам в атрибутах и ​​тексте (в тот момент я не знал об этом инструменте OWASP).

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