Wiki Markup |
---|
Java's regular expression facilities are wide ranging and powerful which can lead to unwanted modification of the original regular expression string to form a pattern that matches too widely, possibly resulting in far too much information being matched. |
...
The primary means of preventing this vulnerability is to sanitize a regular expression string coming from untrusted input. Additionally, the programmer should look into ways of avoiding using regular expressions from untrusted input, or perhaps provide only a very limited subset of regular expression functionality to the user |
...
Constructs and properties of Java regular expressions to watch out for include: |
...
* match flags used in non-capturing groups (These override matching options that may or may not have been passed into the compile() method. |
...
Since Java regular expressions are similar to Perl, it is a good idea to apply lessons learned from Perl regex.
Noncompliant Code Example
This class does not sanitize the incoming regular expression, and as a result, exposes too much information to the user.
This program searches a database of users for usernames that match a regular expression.
No Format |
---|
* Greediness
Since Java regular expressions are similar to Perl, it is a good idea to apply lessons learned from Perl regex.
h2. Noncompliant Code Example
This class does not sanitize the incoming regular expression, and as a result, exposes too much information to the user.
This program searches a database of users for usernames that match a regular expression.
{noformat}
A non-malicious example would be to search for 'John.*'. A malicious example would be to search for '(?s)John.*'
|
Code Block |
{noformat} {code:bgColor=#FFCCCC} {code} import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.Set; import java.util.HashSet; public class ForumUserMan {    private final String userCSV = "JohnPaul,HearsGodsVoice\nJohnJackson,OlympicBobsleder\nJohnMayer,MakesBadMusic\n";    public Set<String> searchUser(String name)    {        Set<String> matchedUsers = new HashSet<String>();        String regex = name + ","; //supposedly this forces the regex to only match names        Pattern p = Pattern.compile(regex, 0);        Matcher m = p.matcher(userCSV);        while (m.find())            matchedUsers.add(m.group());    return matchedUsers;    } } {code} When searching using the regex '(?s)John.*', the program returns all the users' passwords. The (?s) turns on single-line matching support, which means new lines are ignored. |
...
h2. Compliant Solution |
...
It is very difficult to filter out overly permissive regular expressions. It might be easier and more secure to rewrite the application to limit the usage of regular expressions. |
...
For the above code sample, the easy solution is to parse the CSV into a class and limit the regular expression over the name field of the User class. |
...
Code Block |
---|
{code:bgColor=#ccccff} {code} import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.HashMap; /* Usage Test2 <regex>  * Regex is used directly without santization causing sensitive data to be exposed  *  * Imagine this program searches a database of users for usernames that match a regex  * Non malicious usage: Test1 John.*  * Malicious usage: (?s)John.*  */ public class Test2 {    public static class User    {       String name, password;       public User(String name, String password)       {          setName(name);          setPassword(password);       }       private void setName(String n) { name = n; }       private void setPassword(String pw) { password = pw; }       public String getName() { return name; }    }    public static void main(String[] args)    {       if (args.length < 1) {          System.err.println("Failed to specify a regex");          return;       }       String sensitiveData; //represents sensitive data from a file or something       int flags;       String regex;       Pattern p;       Matcher m;       HashMap<String, User> userMap = new HashMap<String, User>();       //imagine a CSV style database: user,password       sensitiveData = "JohnPaul,HearsGodsVoice\nJohnJackson,OlympicBobsleder\nJohnMayer,MakesBadMusic\n";       String[] csvUsers = sensitiveData.split("\n");       for (String csvUser : csvUsers) {          String[] csvUserSplit = csvUser.split(",");          String name = csvUserSplit[0];          String pw = csvUserSplit[1];          User u = new User(name, pw);          userMap.put(name, u);       }       regex = args[0];       flags = 0;       System.out.println("Pattern: \'" + regex + "\'");       p = Pattern.compile(regex, flags);       for (String u : userMap.keySet()) {          m = p.matcher(u);          while (m.find())             System.out.println("Found \'" + m.group() + "\'");       }       System.err.println("DONE");    } } |
Risk Assessment
Rule | Severity | Liklihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
IDS18-J | medium | unlikely | high |
|
|
References
CWE ID 625 Permissive Regular Expressions
...
{code} h2. Risk Assessment || Rule || Severity \\ || Liklihood \\ || Remediation Cost \\ || Priority \\ || Level \\ || | IDS18-J \\ | medium \\ | unlikely \\ | high \\ | | | h2. References [CWE ID 625|http://cwe.mitre.org/data/definitions/625.html] Permissive Regular Expressions \[CVE-2005-1949\|[http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2005-1949|http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2005-1949]\] Arbitrary command execution in ePing plugin for e107 portal due to an overly permissive regular expression parsing an IP |