56 lines
2.5 KiB
Plaintext
56 lines
2.5 KiB
Plaintext
Most of the regular expression engines use ``++backtracking++`` to try all possible execution paths of the regular expression when evaluating an input, in some cases it can cause performance issues, called ``++catastrophic backtracking++`` situations. In the worst case, the complexity of the regular expression is exponential in the size of the input, this means that a small carefully-crafted input (like 20 chars) can trigger ``++catastrophic backtracking++`` and cause a denial of service of the application. Super-linear regex complexity can lead to the same impact too with, in this case, a large carefully-crafted input (thousands chars).
|
|
|
|
|
|
The first regex evaluation will never end in ``++OpenJDK++`` +<=+ 9 and the second regex evaluation will never end in any versions of ``++OpenJDK++``:
|
|
|
|
|
|
----
|
|
java.util.regex.Pattern.compile("(a+)+").matcher(
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+
|
|
aaaaaaaaaaaaaaa!").matches(); // Sensitive
|
|
|
|
java.util.regex.Pattern.compile("(h|h|ih(((i|a|c|c|a|i|i|j|b|a|i|b|a|a|j))+h)ahbfhba|c|i)*").matcher(
|
|
"hchcchicihcchciiicichhcichcihcchiihichiciiiihhcchi"+
|
|
"cchhcihchcihiihciichhccciccichcichiihcchcihhicchcciicchcccihiiihhihihihi"+
|
|
"chicihhcciccchihhhcchichchciihiicihciihcccciciccicciiiiiiiiicihhhiiiihchccch"+
|
|
"chhhhiiihchihcccchhhiiiiiiiicicichicihcciciihichhhhchihciiihhiccccccciciihh"+
|
|
"ichiccchhicchicihihccichicciihcichccihhiciccccccccichhhhihihhcchchihih"+
|
|
"iihhihihihicichihiiiihhhhihhhchhichiicihhiiiiihchccccchichci").matches(); // Sensitive
|
|
----
|
|
|
|
It is not recommended to construct a regular expression pattern from a user-controlled input, if no other choice, sanitize the input to remove/annihilate regex metacharacters.
|
|
|
|
== Noncompliant Code Example
|
|
|
|
----
|
|
public boolean validate(javax.servlet.http.HttpServletRequest request) {
|
|
String regex = request.getParameter("regex");
|
|
String input = request.getParameter("input");
|
|
|
|
input.matches(regex); // Noncompliant
|
|
}
|
|
----
|
|
|
|
== Compliant Solution
|
|
|
|
----
|
|
public boolean validate(javax.servlet.http.HttpServletRequest request) {
|
|
String regex = request.getParameter("regex");
|
|
String input = request.getParameter("input");
|
|
|
|
input.matches(Pattern.quote(regex)); // Compliant : with Pattern.quote metacharacters or escape sequences will be given no special meaning
|
|
}
|
|
----
|
|
|
|
include::../see.adoc[]
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
'''
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
include::../comments-and-links.adoc[]
|
|
endif::env-github,rspecator-view[]
|