Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: updated CS/NCE code again. now i'm done--please review

...

Code Block
bgColor#FFCCCC
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LogSearch {
	public static void FindLogEntry(String search) {
		// Construct regex dynamically from user string
		String regex = "(.*? +public\\[\\d+\\] +.*" + search + ".*)";
		Pattern keywordPatternsearchPattern = Pattern.compile(regex);
		try (FileInputStream fis = new FileInputStream("log.txt")) {
			FileChannel channel = fis.getChannel();
			// Get the file's size and map it into memory
			long size = channel.size();
			final MappedByteBuffer mappedBuffer = channel.map(
					FileChannel.MapMode.READ_ONLY, 0, size);
			Charset charset = Charset.forName("ISO-8859-15");
			final CharsetDecoder decoder = charset.newDecoder();
			// Read file into char buffer
			CharBuffer log = decoder.decode(mappedBuffer);
			Matcher logMatcher = keywordPatternsearchPattern.matcher(log);
			while (logMatcher.find()) {
				String match = logMatcher.group();
				if (match != null!match.isEmpty()) {
				  	System.out.println(match);
				}
			}
		} catch (IOException ex) {
			System.err.println("thrown exception: " + ex.toString());
			Throwable[] suppressed = ex.getSuppressed();
			for (int i = 0; i < suppressed.length; i++) {
				System.err.println("suppressed exception: "
						+ suppressed[i].toString());
			}
		} 
		return;
	}
	public static void main(String[] args) {
		FindLogEntry(args[0]);
	}
}

This code permits an attacker to perform a regex injection.  

Compliant Solution (Whitelisting)

This compliant solution filters sanitizes the search terms at the beginning of the FindLogEntry(), filtering out nonalphanumeric characters (except space and single quote) from the search string, which prevents regex injection.

Code Block
bgColor#ccccff
public class Keywords {
  // ...
  	public static Set<String>void suggestSearchesFindLogEntry(String search) {
		// Sanitize   synchronized (lock) {
      Set<String> searches = new HashSet<String>();

      search string
		StringBuilder sb = new StringBuilder(search.length());
      		for (int i = 0; i < search.length(); ++i) {
        			char ch = search.charAt(i);
        			if (Character.isLetterOrDigit(ch) ||
            ch == ' ' ||
            ch == '\'') {
          				sb.append(ch);
        }
      }
      			}
		}
		search = sb.toString();

      		
		// Construct regex dynamically from user string
      String regex =// "(.*? +public\\[\\d+\\] +.*" + search + ".*)";
      // ...
    }
  }
}

This solution also limits the set of valid prevents regex injection but also restricts search terms. For instanceexample, a user may no longer search for "name =" because the = character would be sanitized out of the regexnonalphanumeric characters are removed from the search term.

Compliant Solution

Another method of mitigating this vulnerability is to filter out the sensitive information prior to matching. Such a solution would require the filtering to be done every time the log file is periodically refreshed, incurring extra complexity and a performance penalty. Sensitive information may still be exposed if the log format changes but the class is not also refactored to accommodate these changes.

...