Created
November 12, 2013 01:35
-
-
Save esamson/7423906 to your computer and use it in GitHub Desktop.
Source file changes between Stinger-2.2 and Stinger-2.2.2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -ur Stinger-2.2/src/org/owasp/stinger/Stinger.java Stinger-2.2.2/src/org/owasp/stinger/Stinger.java | |
--- Stinger-2.2/src/org/owasp/stinger/Stinger.java 2006-11-21 21:11:16.000000000 +0800 | |
+++ Stinger-2.2.2/src/org/owasp/stinger/Stinger.java 2007-12-20 11:04:30.000000000 +0800 | |
@@ -44,12 +44,15 @@ | |
private static RuleSet set = null; | |
+ private static boolean debug = false; | |
+ | |
private Stinger() { | |
} | |
- public static Stinger getInstance(RuleSet ruleSet) { | |
+ public static Stinger getInstance(RuleSet ruleSet, boolean debugIn) { | |
setRuleSet(ruleSet); | |
+ setDebug(debugIn); | |
return instance; | |
} | |
@@ -57,6 +60,10 @@ | |
set = ruleSet; | |
} | |
+ public static void setDebug(boolean debugIn) { | |
+ debug = debugIn; | |
+ } | |
+ | |
private void handleViolationActions(MutableHttpRequest request, HttpServletResponse response, Violation violation) throws BreakChainException { | |
LinkedList actions = null; | |
Iterator itr = null; | |
@@ -80,6 +87,7 @@ | |
while(itr.hasNext()) { | |
violation = (Violation)itr.next(); | |
+ if (debug) System.out.println("Handling violation " + violation.toString()); | |
handleViolationActions(request, response, violation); | |
} | |
@@ -115,7 +123,7 @@ | |
if(!cookieMap.containsKey(cRule.getName()) && !cRule.isCreatedUri(uri) && cRule.isEnforced(uri)) { | |
violation = new Violation(cRule.getMissing(), name, null, cRule.getPattern(), uri); | |
- System.out.println("[Stinger-Filter] VIOLATION: Cookie " + cRule.getName() + " is missing"); | |
+ if (debug) System.out.println("[Stinger-Filter] VIOLATION: Cookie " + cRule.getName() + " is missing"); | |
if(violation.getSeverity().equals(Severity.FATAL)) { | |
handleViolationActions(request, response, violation); | |
@@ -130,7 +138,7 @@ | |
} | |
} else { | |
/** There exists no rules for this URI **/ | |
- System.out.println("[Stinger-Filter] Warning: There exists no cookie rules"); | |
+ if (debug) System.out.println("[Stinger-Filter] Warning: There exists no cookie rules"); | |
} | |
} | |
@@ -154,7 +162,7 @@ | |
if(!cRule.isValid(cookie.getValue())) { | |
violation = new Violation(cRule.getMissing(), name, cookie.getValue(), cRule.getPattern(), uri); | |
- System.out.println("[Stinger-Filter] VIOLATION: Cookie " + cRule.getName() + " is malformed"); | |
+ if (debug) System.out.println("[Stinger-Filter] VIOLATION: Cookie " + cRule.getName() + " is malformed"); | |
if(violation.getSeverity().equals(Severity.FATAL)) { | |
handleViolationActions(request, response, violation); | |
@@ -193,7 +201,7 @@ | |
if(!name.equals(RuleSet.STINGER_ALL) && (request.getParameter(name) == null || request.getParameter(name).equals(""))) { | |
violation = new Violation(pRule.getMissing(), name, null, pRule.getPattern(), uri); | |
- System.out.println("[Stinger-Filter] VIOLATION: Parameter " + name + " is missing"); | |
+ if (debug) System.out.println("[Stinger-Filter] VIOLATION: Parameter " + name + " is missing"); | |
if(violation.getSeverity().equals(Severity.FATAL)) { | |
@@ -209,14 +217,14 @@ | |
} | |
} else { | |
/** There exists no rules for this uri **/ | |
- System.out.println("[Stinger-Filter] Warning: There exists no rules for the uri " + uri); | |
+ if (debug) System.out.println("[Stinger-Filter] Warning: There exists no rules for the uri " + uri); | |
} | |
} | |
private void checkMalformedParameters(MutableHttpRequest request, HttpServletResponse response, ViolationList vList) throws BreakChainException { | |
String uri = null; | |
String name = null; | |
- String value = null; | |
+ String[] values = null; | |
Rule pRule = null; | |
Enumeration e = null; | |
Violation violation = null; | |
@@ -226,39 +234,74 @@ | |
while(e.hasMoreElements()) { | |
name = (String)e.nextElement(); | |
- value = request.getParameter(name); | |
+ values = request.getParameterValues(name); | |
pRule = set.getParameterRule(uri, name); | |
- if(pRule != null && !pRule.isValid(value)) { | |
- violation = new Violation(pRule.getMalformed(), name, value, pRule.getPattern(), uri); | |
- | |
- System.out.println("[Stinger-Filter] VIOLATION: Parameter " + name + " is malformed"); | |
- | |
- if(violation.getSeverity().equals(Severity.FATAL)) { | |
- handleViolationActions(request, response, violation); | |
+ for (int i=0;i<values.length;i++){ | |
+ String value = values[i]; | |
+ if(pRule != null && !pRule.isValid(value)) { | |
+ violation = new Violation(pRule.getMalformed(), name, value, pRule.getPattern(), uri); | |
+ | |
+ if (debug) System.out.println("[Stinger-Filter] VIOLATION: Parameter " + name + " is malformed"); | |
- throw new BreakChainException("Chain broken due to fatal violation"); | |
- } else if(violation.getSeverity().equals(Severity.CONTINUE)){ | |
- vList.add(violation); | |
- } else { | |
- /** Severity == IGNORE **/ | |
+ if(violation.getSeverity().equals(Severity.FATAL)) { | |
+ handleViolationActions(request, response, violation); | |
+ | |
+ throw new BreakChainException("Chain broken due to fatal violation"); | |
+ } else if(violation.getSeverity().equals(Severity.CONTINUE)){ | |
+ vList.add(violation); | |
+ } else { | |
+ /** Severity == IGNORE **/ | |
+ } | |
} | |
} | |
} | |
} | |
+ private void checkMalformedUri(MutableHttpRequest request, HttpServletResponse response, ViolationList vList) throws BreakChainException { | |
+ String uri = null; | |
+ String name = null; | |
+ String[] values = null; | |
+ Rule pRule = null; | |
+ Enumeration e = null; | |
+ Violation violation = null; | |
+ | |
+ uri = request.getRequestURI(); | |
+ | |
+ pRule = set.getParameterRule(uri, "uri"); | |
+ System.out.println("Checking uri: " + uri); | |
+ String value = new String(request.getRequestURL()); | |
+ if(pRule != null && !pRule.isValid(value)) { | |
+ violation = new Violation(pRule.getMalformed(), name, value, pRule.getPattern(), uri); | |
+ | |
+ if (debug) System.out.println("[Stinger-Filter] VIOLATION: Parameter " + name + " is malformed"); | |
+ | |
+ if(violation.getSeverity().equals(Severity.FATAL)) { | |
+ handleViolationActions(request, response, violation); | |
+ | |
+ throw new BreakChainException("Chain broken due to fatal violation"); | |
+ } else if(violation.getSeverity().equals(Severity.CONTINUE)){ | |
+ vList.add(violation); | |
+ } else { | |
+ /** Severity == IGNORE **/ | |
+ } | |
+ } | |
+ } | |
+ | |
public void validate(MutableHttpRequest request, HttpServletResponse response) throws BreakChainException { | |
ViolationList vList = new ViolationList(); | |
vList = new ViolationList(); | |
+ checkMalformedUri(request, response, vList); | |
checkMissingCookies(request, response, vList); | |
checkMalformedCookies(request, response, vList); | |
checkMissingParameters(request, response, vList); | |
checkMalformedParameters(request, response, vList); | |
/** No fatal violations, process actions for non-fatal violations **/ | |
+ if (debug)System.out.println("Now handle any stinger violations"); | |
handleViolations(request, response, vList); | |
} | |
} | |
diff -ur Stinger-2.2/src/org/owasp/stinger/StingerFilter.java Stinger-2.2.2/src/org/owasp/stinger/StingerFilter.java | |
--- Stinger-2.2/src/org/owasp/stinger/StingerFilter.java 2006-11-21 21:19:56.000000000 +0800 | |
+++ Stinger-2.2.2/src/org/owasp/stinger/StingerFilter.java 2008-11-12 11:52:58.000000000 +0800 | |
@@ -35,9 +35,14 @@ | |
import org.owasp.stinger.http.MutableHttpRequest; | |
import org.owasp.stinger.rules.RuleSet; | |
+ | |
public class StingerFilter implements Filter { | |
- private Stinger stinger = null; | |
+ private final static String POST = "POST"; | |
+ | |
+ private final static String URL_FORM_ENCODING = "application/x-www-form-urlencoded"; | |
+ | |
+ private Stinger stinger = null; | |
private String config = null; | |
@@ -47,42 +52,63 @@ | |
private String errorPage = null; | |
+ public boolean debug = false; | |
+ | |
public void init(FilterConfig filterConfig) { | |
- | |
+ System.out.println("Initializing Stinger"); | |
+ /** Load the the debug parm **/ | |
+ debug = Boolean.valueOf(filterConfig.getInitParameter("debug")).booleanValue(); | |
+ System.out.println("Debugging set to " + String.valueOf(debug)); | |
/** Pull config location from Filter init parameter **/ | |
config = filterConfig.getInitParameter("config"); | |
- ruleSet = new RuleSet(config); | |
+ ruleSet = new RuleSet(config, debug); | |
/** Error page to display when exceptions are thrown **/ | |
errorPage = filterConfig.getInitParameter("error-page"); | |
/** Should we dynamically load the ruleset? **/ | |
- reload = Boolean.getBoolean(filterConfig.getInitParameter("reload")); | |
+ reload = Boolean.valueOf(filterConfig.getInitParameter("reload")).booleanValue(); | |
+ if (debug) System.out.println("Reload parm is: " + String.valueOf(reload)); | |
/** Get the stinger instance **/ | |
- stinger = Stinger.getInstance(ruleSet); | |
+ stinger = Stinger.getInstance(ruleSet, debug); | |
} | |
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { | |
MutableHttpRequest mRequest = null; | |
HttpServletResponse hResponse = null; | |
+ | |
if(request instanceof HttpServletRequest && response instanceof HttpServletResponse) { | |
mRequest = new MutableHttpRequest((HttpServletRequest)request); | |
hResponse = (HttpServletResponse)response; | |
+ | |
if(reload) { | |
initRuleSet(); | |
} | |
try { | |
- if(!ruleSet.isExcluded(mRequest.getRequestURI())) { | |
- stinger.validate(mRequest, hResponse); | |
- } | |
- | |
- chain.doFilter(mRequest, hResponse); | |
- | |
- } catch (BreakChainException bce) { | |
+ if(isValidRequest(mRequest)) { | |
+ if(!ruleSet.isExcluded(mRequest.getRequestURI())) { | |
+ stinger.validate(mRequest, hResponse); | |
+ } | |
+ | |
+ if (debug)System.out.println("We're done processing, so do next filter in the chain"); | |
+ //mRequest.loadWLRequest(wlRequest); | |
+ //wlRequest.setParameter("blah", "blah"); | |
+ chain.doFilter(mRequest, hResponse); | |
+ } else { | |
+ System.out.println("[Stinger-Filter] caught a POST request with an incorrect content type header (" + mRequest.getContentType() + ") . Redirected to error page at " + errorPage); | |
+ hResponse.sendRedirect(errorPage); | |
+ } | |
+ } | |
+ catch (BreakChainException bce) { | |
bce.printStackTrace(); | |
+ try { | |
+ hResponse.sendRedirect(errorPage); | |
+ } catch (IOException ioe) { | |
+ ioe.printStackTrace(); | |
+ } | |
} catch(Exception e) { | |
e.printStackTrace(); | |
@@ -94,13 +120,39 @@ | |
} | |
} | |
} | |
- | |
+ | |
+ /** | |
+ * MULTIPART VALIDATION BYPASS FIX: | |
+ * | |
+ * The Stinger validation relies on the J2EE servlet framework. | |
+ * By default, the framework only supports standard url-form-encoding | |
+ * for POST requests. If a multipart request comes through, however, | |
+ * request.getParameterNames() will return an empty enumeration. As a | |
+ * quick fix, we do not currently accept multipart-form-encoded post | |
+ * requests. | |
+ * @param request | |
+ * @return | |
+ */ | |
+ private boolean isValidRequest(MutableHttpRequest request) | |
+ { | |
+ boolean valid = true; | |
+ String method = request.getMethod(); | |
+ String header = request.getContentType(); | |
+ | |
+ if(POST.equalsIgnoreCase(method) && !URL_FORM_ENCODING.equalsIgnoreCase(header)) | |
+ { | |
+ valid = false; | |
+ } | |
+ | |
+ return valid; | |
+ } | |
+ | |
public void destroy() { | |
} | |
private synchronized void initRuleSet() { | |
- ruleSet = new RuleSet(config); | |
+ ruleSet = new RuleSet(config, debug); | |
Stinger.setRuleSet(ruleSet); | |
} | |
} | |
diff -ur Stinger-2.2/src/org/owasp/stinger/actions/Encode.java Stinger-2.2.2/src/org/owasp/stinger/actions/Encode.java | |
--- Stinger-2.2/src/org/owasp/stinger/actions/Encode.java 2006-11-19 20:32:56.000000000 +0800 | |
+++ Stinger-2.2.2/src/org/owasp/stinger/actions/Encode.java 2007-09-27 15:19:18.000000000 +0800 | |
@@ -36,7 +36,7 @@ | |
if(value != null) { | |
result = EntityEncoder.HTMLEntityEncode(value); | |
- request.addParameter(name, result); | |
+ request.replaceParameterValue(name, value, result); | |
} | |
} | |
@@ -45,7 +45,7 @@ | |
String value = null; | |
name = violation.getName(); | |
- value = request.getParameter(name); | |
+ value = violation.getValue(); | |
entityEncode(request, name, value); | |
} | |
diff -ur Stinger-2.2/src/org/owasp/stinger/actions/Log.java Stinger-2.2.2/src/org/owasp/stinger/actions/Log.java | |
--- Stinger-2.2/src/org/owasp/stinger/actions/Log.java 2006-11-21 21:18:12.000000000 +0800 | |
+++ Stinger-2.2.2/src/org/owasp/stinger/actions/Log.java 2007-11-27 14:19:48.000000000 +0800 | |
@@ -57,7 +57,7 @@ | |
message = message.replaceAll("%ip", request.getRemoteAddr()); | |
/** Offender's Port **/ | |
- message = message.replaceAll("%port", String.valueOf(request.getRemotePort())); | |
+// message = message.replaceAll("%port", String.valueOf(request.getRemotePort())); | |
/** Offending parameter name **/ | |
if(violation.getName() != null) { | |
@@ -94,6 +94,7 @@ | |
logger.log(new LogRecord(Level.parse(level.toUpperCase()), message)); | |
handler.flush(); | |
+ //handler.close(); | |
} | |
private synchronized FileHandler getHandler(String log, String limit, String count, String append) { | |
Only in sz222/src/org/owasp/stinger/actions: Scrub.java | |
diff -ur Stinger-2.2/src/org/owasp/stinger/http/MutableHttpRequest.java Stinger-2.2.2/src/org/owasp/stinger/http/MutableHttpRequest.java | |
--- Stinger-2.2/src/org/owasp/stinger/http/MutableHttpRequest.java 2006-11-21 21:14:54.000000000 +0800 | |
+++ Stinger-2.2.2/src/org/owasp/stinger/http/MutableHttpRequest.java 2008-11-12 11:46:12.000000000 +0800 | |
@@ -30,6 +30,7 @@ | |
import java.util.LinkedList; | |
import javax.servlet.ServletRequest; | |
+import javax.servlet.ServletRequestWrapper; | |
import javax.servlet.http.Cookie; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletRequestWrapper; | |
@@ -37,9 +38,13 @@ | |
public class MutableHttpRequest extends HttpServletRequestWrapper { | |
private HttpServletRequest request = null; | |
+ private ServletRequestWrapper srw = null; | |
+ | |
private Map headers = new HashMap(); | |
+ private LinkedList headerNames = new LinkedList(); | |
+ | |
private Map cookies = new HashMap(); | |
private Map parameters = new HashMap(); | |
@@ -52,18 +57,24 @@ | |
while(e.hasMoreElements()) { | |
String name = (String)e.nextElement(); | |
- String value = request.getHeader(name); | |
- LinkedList list = (LinkedList)headers.get(name); | |
+ Enumeration values = request.getHeaders(name); | |
+ headerNames.add(name); | |
+ String lowerName = name.toLowerCase(); | |
+ LinkedList list = (LinkedList)headers.get(lowerName); | |
- if(list != null) { | |
- list.add(value); | |
- } else { | |
- list = new LinkedList(); | |
- list.add(value); | |
- headers.put(name, list); | |
+ while (values.hasMoreElements()){ | |
+ String value = (String)values.nextElement(); | |
+ if(list != null) { | |
+ list.add(value); | |
+ } else { | |
+ list = new LinkedList(); | |
+ list.add(value); | |
+ headers.put(lowerName, list); | |
+ } | |
} | |
} | |
+ | |
Cookie[] c = request.getCookies(); | |
if(c != null) { | |
@@ -76,9 +87,9 @@ | |
while(e.hasMoreElements()) { | |
String name = (String)e.nextElement(); | |
- String value = request.getParameter(name); | |
+ String[] values = request.getParameterValues(name); | |
- parameters.put(name, value); | |
+ parameters.put(name, values); | |
} | |
} | |
@@ -87,11 +98,35 @@ | |
} | |
public String getParameter(String name) { | |
- return (String)parameters.get(name); | |
+ String[] values = (String[])parameters.get(name); | |
+ return values!=null? values[0]:null; | |
} | |
public void addParameter(String name, String value) { | |
- parameters.put(name, value); | |
+ String[] values = (String[])parameters.get(name); | |
+ String[] newValues = new String[values.length+1]; | |
+ int i=0; | |
+ for (i=0;i<values.length;i++){ | |
+ newValues[i] = values[i]; | |
+ } | |
+ newValues[i] = value; | |
+ parameters.put(name, newValues); | |
+ } | |
+ | |
+ public void replaceParameterValue(String name, String oldValue, String newValue) { | |
+ if (name == null || oldValue == null || newValue == null) return; | |
+ String[] values = (String[])parameters.get(name); | |
+ String[] newValues = new String[values.length]; | |
+ int i=0; | |
+ for (i=0;i<values.length;i++){ | |
+ if (oldValue.equals(values[i])) { | |
+ newValues[i] = newValue; | |
+ } | |
+ else { | |
+ newValues[i] = values[i]; | |
+ } | |
+ } | |
+ parameters.put(name, newValues); | |
} | |
public void removeParameter(String name) { | |
@@ -103,20 +138,20 @@ | |
} | |
public Map getParameterMap() { | |
- return parameters; | |
+ return new HashMap(parameters); | |
} | |
public Enumeration getParameterNames() { | |
return Collections.enumeration(parameters.keySet()); | |
} | |
- public String[] getParameterValues() { | |
- Collection c = parameters.values(); | |
- Enumeration e = Collections.enumeration(c); | |
- String[] values = new String[c.size()]; | |
+ public String[] getParameterValues(String name) { | |
+ | |
+ String[] myVals = (String[])parameters.get(name); | |
+ String[] values = new String[myVals.length]; | |
for(int i=0; i<values.length; i++) { | |
- values[i] = (String)e.nextElement(); | |
+ values[i] = new String(myVals[i]); | |
} | |
return values; | |
@@ -153,7 +188,7 @@ | |
public String getHeader(String name) { | |
String header = null; | |
- LinkedList values = (LinkedList)headers.get(name); | |
+ LinkedList values = (LinkedList)headers.get(name.toLowerCase()); | |
if(values != null) { | |
header = (String)values.getFirst(); | |
@@ -175,11 +210,11 @@ | |
} | |
public Enumeration getHeaderNames() { | |
- return Collections.enumeration(headers.keySet()); | |
+ return Collections.enumeration(headerNames); | |
} | |
public Enumeration getHeaders(String name) { | |
- return Collections.enumeration((Collection)headers.get(name)); | |
+ return Collections.enumeration((Collection)headers.get(name.toLowerCase())); | |
} | |
public int getIntHeader(String name) throws NumberFormatException { | |
@@ -193,4 +228,5 @@ | |
return result; | |
} | |
+ | |
} | |
diff -ur Stinger-2.2/src/org/owasp/stinger/rules/Rule.java Stinger-2.2.2/src/org/owasp/stinger/rules/Rule.java | |
--- Stinger-2.2/src/org/owasp/stinger/rules/Rule.java 2006-11-21 21:15:20.000000000 +0800 | |
+++ Stinger-2.2.2/src/org/owasp/stinger/rules/Rule.java 2007-09-26 14:02:30.000000000 +0800 | |
@@ -50,7 +50,7 @@ | |
} | |
public String getPattern() { | |
- return pattern.toString(); | |
+ return pattern.pattern(); | |
} | |
public void setPattern(String regex) { | |
diff -ur Stinger-2.2/src/org/owasp/stinger/rules/RuleSet.java Stinger-2.2.2/src/org/owasp/stinger/rules/RuleSet.java | |
--- Stinger-2.2/src/org/owasp/stinger/rules/RuleSet.java 2006-11-21 21:19:28.000000000 +0800 | |
+++ Stinger-2.2.2/src/org/owasp/stinger/rules/RuleSet.java 2007-12-10 10:40:22.000000000 +0800 | |
@@ -63,9 +63,12 @@ | |
/** Map of all regular expressions **/ | |
private HashMap regexs = new HashMap(); | |
+ private boolean debug = false; | |
+ | |
private Document parseXmlFile(String fileName) { | |
Document doc = null; | |
DocumentBuilderFactory bf = null; | |
+ if (debug) System.out.println("Stinger SVDL: " + fileName); | |
try { | |
bf = DocumentBuilderFactory.newInstance(); | |
@@ -81,7 +84,8 @@ | |
} | |
- public RuleSet(String config) { | |
+ public RuleSet(String config, boolean debugIn) { | |
+ debug = debugIn; | |
parseRules(config); | |
} | |
@@ -205,6 +209,7 @@ | |
private void parseRules(String config) { | |
Document d = parseXmlFile(config); | |
+ if (debug) System.out.println(config); | |
Element root = d.getDocumentElement(); | |
Element regexset = null; | |
Element e = null; | |
@@ -337,7 +342,7 @@ | |
uriRules = getRules(uri); | |
if(uriRules == null) { | |
- System.out.println("[Stinger-Filter](Warning): using default parameter rule for parameter " + parameterName); | |
+ if (debug) System.out.println("[Stinger-Filter](Warning): using default parameter rule for parameter " + parameterName); | |
uriRules = getRules(STINGER_DEFAULT); | |
rule = (Rule)uriRules.get(STINGER_ALL); | |
} else { | |
@@ -394,7 +399,7 @@ | |
} | |
} else { | |
/** Get Default Rules **/ | |
- System.out.println("[Stinger-Filter](WARNING): using default rules for uri " + uri); | |
+ if (debug) System.out.println("[Stinger-Filter](WARNING): using default rules for uri " + uri); | |
uriRules = getRules(STINGER_DEFAULT); | |
result.add(uriRules.get(STINGER_ALL)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment