CodeQL documentation

Regular expression injection

ID: java/regex-injection Kind: path-problem Security severity: 7.5 Severity: error Precision: high Tags: - security - external/cwe/cwe-730 - external/cwe/cwe-400 Query suites: - java-code-scanning.qls - java-security-extended.qls - java-security-and-quality.qls 

Click to see the query in the CodeQL repository

Constructing a regular expression with unsanitized user input is dangerous as a malicious user may be able to modify the meaning of the expression. In particular, such a user may be able to provide a regular expression fragment that takes exponential time in the worst case, and use that to perform a Denial of Service attack.

Recommendation

Before embedding user input into a regular expression, use a sanitization function such as Pattern.quote to escape meta-characters that have special meaning.

Example

The following example shows an HTTP request parameter that is used to construct a regular expression.

In the first case the user-provided regex is not escaped. If a malicious user provides a regex whose worst-case performance is exponential, then this could lead to a Denial of Service.

In the second case, the user input is escaped using Pattern.quote before being included in the regular expression. This ensures that the user cannot insert characters which have a special meaning in regular expressions.

import java.util.regex.Pattern; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; public class RegexInjectionDemo extends HttpServlet {  public boolean badExample(javax.servlet.http.HttpServletRequest request) {  String regex = request.getParameter("regex");  String input = request.getParameter("input");  // BAD: Unsanitized user input is used to construct a regular expression  return input.matches(regex);  }  public boolean goodExample(javax.servlet.http.HttpServletRequest request) {  String regex = request.getParameter("regex");  String input = request.getParameter("input");  // GOOD: User input is sanitized before constructing the regex  return input.matches(Pattern.quote(regex));  } } 

References