package com.nvarghese.beowulf.sfe.webtest.library;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.nvarghese.beowulf.sfe.ConfigurationManager;
public class SqlInjectionLibrary {
private static HashMap<String, Set<Pattern>> errorRegexs;
private static Set<Pattern> generalErrorRegexs;
private static boolean initialized = false;
public final static String GENERAL = "unknown";
public final static String MSSQL = "Microsoft SQL Server";
public final static String MYSQL = "MySQL";
public final static String POSTGRESQL = "PostgreSQL";
public final static String ORACLE = "Oracle";
public final static String MSACCESS = "Microsoft Access";
public final static String DB2 = "IBM DB2";
public final static String SYBASE = "Sybase";
public final static String INFORMIX = "IBM Informix";
static Logger logger = LoggerFactory.getLogger(SqlInjectionLibrary.class);
private synchronized static void initializeLibrary() {
if (!initialized) {
errorRegexs = new HashMap<String, Set<Pattern>>(7);
generalErrorRegexs = generatePatterns(ConfigurationManager.getScannerConfiguration()
.getList("sql_injection.error_message_regexs.general"));
errorRegexs.put(SqlInjectionLibrary.MSSQL,
generatePatterns(ConfigurationManager.getScannerConfiguration().getList("sql_injection.error_message_regexs.mssql")));
errorRegexs.put(SqlInjectionLibrary.MYSQL,
generatePatterns(ConfigurationManager.getScannerConfiguration().getList("sql_injection.error_message_regexs.mysql")));
errorRegexs.put(SqlInjectionLibrary.POSTGRESQL,
generatePatterns(ConfigurationManager.getScannerConfiguration().getList("sql_injection.error_message_regexs.postgresql")));
errorRegexs.put(SqlInjectionLibrary.ORACLE,
generatePatterns(ConfigurationManager.getScannerConfiguration().getList("sql_injection.error_message_regexs.oracle")));
errorRegexs.put(SqlInjectionLibrary.MSACCESS,
generatePatterns(ConfigurationManager.getScannerConfiguration().getList("sql_injection.error_message_regexs.access")));
errorRegexs.put(SqlInjectionLibrary.DB2,
generatePatterns(ConfigurationManager.getScannerConfiguration().getList("sql_injection.error_message_regexs.db2")));
errorRegexs.put(SqlInjectionLibrary.SYBASE,
generatePatterns(ConfigurationManager.getScannerConfiguration().getList("sql_injection.error_message_regexs.sybase")));
errorRegexs.put(SqlInjectionLibrary.INFORMIX,
generatePatterns(ConfigurationManager.getScannerConfiguration().getList("sql_injection.error_message_regexs.informix")));
initialized = true;
}
}
private static Set<Pattern> generatePatterns(List<String> rawPatterns) {
Set<Pattern> patterns = new HashSet<Pattern>();
for (String stringPattern : rawPatterns) {
try {
Pattern pattern = Pattern.compile(stringPattern, Pattern.CASE_INSENSITIVE);
patterns.add(pattern);
} catch (Exception e) {
logger.error("Problem loading a SQL error pattern: " + e.getMessage());
}
}
return patterns;
}
/**
* Returns the database platform constant (e.g. SQLInjection.ORACLE), or a
* null if no error was found
*
* @param text
* @return
*/
public static String findSQLErrorMessages(String text) {
initializeLibrary();
if (text == null || text.equals("")) {
return null;
}
// eliminate white space
text = text.replaceAll("[\\x00-\\x20]++", " ");
for (String platform : errorRegexs.keySet()) {
for (Pattern pattern : errorRegexs.get(platform)) {
Matcher m = pattern.matcher(text);
if (m.find()) {
return platform;
}
}
}
// general needs to be tested _after_ all of the platforms are tested
for (Pattern pattern : generalErrorRegexs) {
Matcher m = pattern.matcher(text);
if (m.find()) {
return SqlInjectionLibrary.GENERAL;
}
}
return null;
}
}