Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: made NCCE and CCE into full classes, obey 80 width

...

No Format
 A non-malicious use would be to enter "C" to match Charles and Cecilia. 
 A malicious use would be to enter "?:)(^C,[0-9]+?,[0-9]+?$)|(?:" which
 grabs the IPs that made the search.

The outer parentheses defeat the grouping protection. Using the OR operator allows injection of any arbitrary regex. Now this use will reveal all times and IPs the keyword 'Bono' was searched.

Code Block
bgColor#FFCCCC

import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ExploitableLog
{
    /* Say this logfile contains:
     * CSV style: search string, time (unix), ip (integer)
     *
     * Alice,1267773881,2147651708
     * Bono,1267774881,2147651708
     * Charles,1267775881,1175563058
     * Cecilia,1267773222,291232332
     *
     * and the CSVLog class has a readLine() method which retrieves a single
     * line from the CSVLog and returns null when at EOF
     */
private    private CSVLog logfile;
    
    //* an application repeatedly calls this function that searches through
// the the
     * search log for search suggestions for autocompletion
public     */
    public Set<String> suggestSearches(String search)
    {
   Set<String>     Set<String> searches = new HashSet<String>();
        
        //* constructConstruct regex from user's string   */
         //Regex thematches regexfull matchesvalid validlog lines. andThe the grouping characters will limit the 
         //the returned regexstring to only the search stringkeyword.
       String String regex = "^(" + search + ".*),[0-9]+?,[0-9]+?$";
   Pattern     Pattern p = Pattern.compile(regex);
        
   String     /* Read from log and match regex */
        String s;
       while while ((s = logfile.readLine()) != null) { //gets a single line from the logfile
       Matcher            Matcher m = p.matcher(s);
       if            if (m.find()) {
           String                String found = m.group(1);
           searches                searches.add(found);
                  }
        }
              
       return searches; return searches;
    }
    
    public ExploitableLog()
    {
        logfile = new CSVLog();
    }
    
    public class CSVLog
    {
        //this is supposed to come from a file, but its here as a string for
        //illustrative purposes
        public static final String logString =
            "Alice,1267773881,2147651408\n" +
            "Bono,1267774881,2147351708\n" +
            "Charles,1267775881,1175523058\n" +
            "Cecilia,1267773222,291232332\n";
        
        private String[] log;
        
        private int index;
        
        public CSVLog()
        {
            index = 0;
            log = logString.split("\n");
        }
        
        public String readLine()
        {
            if (index < log.length)
                return log[index++];
            return null;
        }
    }
}

Compliant Solution

Solutions include parsing the CSV into a class prior to matching or whitelisting only certain characters (such as letters and digits). Blacklisting might be difficult due to the variability of the regex language.

Code Block
bgColor#ccccff
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FilteredLog
{
    /* Say this logfile contains:
     * CSV style: search string, time (unix), ip (integer)
     *
     * Alice,1267773881,2147651708
     * Bono,1267774881,2147651708
     * Charles,1267775881,1175563058
     * Cecilia,1267773222,291232332
     *
     * and the CSVLog class has a readLine() method which retrieves a single
     * line from the CSVLog and returns null when at EOF
     */
private    private CSVLog logfile;
    
    //* an application repeatedly calls this function that searches through the
     * search log 
// for search suggestions for autocompletion
public     */
    public Set<String> suggestSearches(String search)
    {
       Set<String> Set<String> searches = new HashSet<String>();
        
        /* //filter search
 Filter user input */
        StringBuilder sb = new StringBuilder(search.length());
         for (int i = 0; i < search.length(); ++i) {
             char ch = search.charAt(i);
             if (Character.isLetterOrDigit(ch))
                 sb.append(ch);
         }
         search = sb.toString();
        
        //construct* Construct regex from user's string   */
         //theRegex regexmatches matchesfull valid log lines. and theThe grouping characters will limit the 
         //the returned regexstring to only the search stringkeyword.
   String     String regex = "^(" + search + ".*),[0-9]+?,[0-9]+?$";
       Pattern Pattern p = Pattern.compile(regex);
        
        /* Read from log and match regex */
       String String s;
   while     while ((s = logfile.readLine()) != null) {
   //gets    a single line from the logfile
       Matcher     Matcher m = p.matcher(s);
       if            if (m.find()) {
           String                String found = m.group(1);
           searches                searches.add(found);
                  }
        }
              
       return searches; return searches;
    }
    
    public FilteredLog()
    {
        logfile = new CSVLog();
    }
    
    public class CSVLog
    {
        //this is supposed to come from a file, but its here as a string for
        //illustrative purposes
        public static final String logString =
            "Alice,1267773881,2147651408\n" +
            "Bono,1267774881,2147351708\n" +
            "Charles,1267775881,1175523058\n" +
            "Cecilia,1267773222,291232332\n";
        
        private String[] log;
        
        private int index;
        
        public CSVLog()
        {
            index = 0;
            log = logString.split("\n");
        }
        
        public String readLine()
        {
            if (index < log.length)
                return log[index++];
            return null;
        }
    }
}

Risk Assessment

Rule

Severity

Liklihood

Remediation Cost

Priority

Level

IDS18-J

medium

probable

high

P8

L2

...