Author: markt Date: Thu Jun 20 10:38:49 2013 New Revision: 1494915 URL: http://svn.apache.org/r1494915 Log: Servlet 3.1 Implement the new deny-uncovered-http-methods element in server.xml
Modified: tomcat/trunk/java/org/apache/catalina/Context.java tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties tomcat/trunk/java/org/apache/catalina/core/StandardContext.java tomcat/trunk/java/org/apache/catalina/deploy/WebXml.java tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java tomcat/trunk/java/org/apache/catalina/startup/FailedContext.java tomcat/trunk/java/org/apache/catalina/startup/WebRuleSet.java tomcat/trunk/test/org/apache/catalina/core/TesterContext.java Modified: tomcat/trunk/java/org/apache/catalina/Context.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Context.java?rev=1494915&r1=1494914&r2=1494915&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/Context.java (original) +++ tomcat/trunk/java/org/apache/catalina/Context.java Thu Jun 20 10:38:49 2013 @@ -329,6 +329,20 @@ public interface Context extends Contain /** + * Return the deny-uncovered-http-methods flag for this web application. + */ + public boolean getDenyUncoveredHttpMethods(); + + + /** + * Set the deny-uncovered-http-methods flag for this web application. + * + * @param denyUncoveredHttpMethods The new deny-uncovered-http-methods flag + */ + public void setDenyUncoveredHttpMethods(boolean denyUncoveredHttpMethods); + + + /** * Return the display name of this web application. */ public String getDisplayName(); Modified: tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties?rev=1494915&r1=1494914&r2=1494915&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties Thu Jun 20 10:38:49 2013 @@ -140,7 +140,9 @@ standardContext.startFailed=Context [{0} standardContext.startingContext=Exception starting Context with name [{0}] standardContext.stoppingContext=Exception stopping Context with name [{0}] standardContext.uncoveredHttpMethod=For security constraints with URL pattern [{0}] only the HTTP methods [{1}] are covered. All other methods are uncovered. +standardContext.uncoveredHttpMethodFix=Adding security constraints with URL pattern [{0}] to deny access with the uncovered HTTP methods that are not one of the following [{1}] standardContext.uncoveredHttpOmittedMethod=For security constraints with URL pattern [{0}] the HTTP methods [{1}] are uncovered. +standardContext.uncoveredHttpOmittedMethodFix=Adding security constraints with URL pattern [{0}] to deny access with the uncovered HTTP methods [{1}] standardContext.urlPattern.patternWarning=WARNING: URL pattern {0} must start with a ''/'' in Servlet 2.4 standardContext.webappClassLoader.missingProperty=Unable to set the web application class loader property [{0}] to [{1}] as the property does not exist. standardContext.workPath=Exception obtaining work path for context [{0}] Modified: tomcat/trunk/java/org/apache/catalina/core/StandardContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardContext.java?rev=1494915&r1=1494914&r2=1494915&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Thu Jun 20 10:38:49 2013 @@ -348,6 +348,9 @@ public class StandardContext extends Con private boolean delegate = false; + private boolean denyUncoveredHttpMethods; + + /** * The display name of this web application. */ @@ -1684,6 +1687,19 @@ public class StandardContext extends Con this.tldScanTime = tldScanTime; } + + @Override + public boolean getDenyUncoveredHttpMethods() { + return denyUncoveredHttpMethods; + } + + + @Override + public void setDenyUncoveredHttpMethods(boolean denyUncoveredHttpMethods) { + this.denyUncoveredHttpMethods = denyUncoveredHttpMethods; + } + + /** * Return the display name of this web application. */ @@ -5345,7 +5361,6 @@ public class StandardContext extends Con private void checkConstraintsForUncoveredMethods() { // TODO - Add an option to lower the log level of any uncovered method // warnings to debug - // TODO - Implement adding constraints to deny uncovered methods Set<String> coveredPatterns = new HashSet<>(); Map<String,Set<String>> urlMethodMap = new HashMap<>(); Map<String,Set<String>> urlOmittedMethodMap = new HashMap<>(); @@ -5419,8 +5434,25 @@ public class StandardContext extends Con msg.append(method); msg.append(' '); } - log.error(sm.getString("standardContext.uncoveredHttpMethod", - pattern, msg.toString().trim())); + if (getDenyUncoveredHttpMethods()) { + log.info(sm.getString( + "standardContext.uncoveredHttpMethodFix", + pattern, msg.toString().trim())); + SecurityCollection collection = new SecurityCollection(); + for (String method : methods) { + collection.addOmittedMethod(method); + } + collection.addPattern(pattern); + collection.setName("deny-uncovered-http-methods"); + SecurityConstraint constraint = new SecurityConstraint(); + constraint.setAuthConstraint(true); + constraint.addCollection(collection); + addConstraint(constraint); + } else { + log.error(sm.getString( + "standardContext.uncoveredHttpMethod", + pattern, msg.toString().trim())); + } continue; } @@ -5434,9 +5466,25 @@ public class StandardContext extends Con msg.append(method); msg.append(' '); } - log.error(sm.getString( - "standardContext.uncoveredHttpOmittedMethod", - pattern, msg.toString().trim())); + if (getDenyUncoveredHttpMethods()) { + log.info(sm.getString( + "standardContext.uncoveredHttpOmittedMethodFix", + pattern, msg.toString().trim())); + SecurityCollection collection = new SecurityCollection(); + for (String method : methods) { + collection.addMethod(method); + } + collection.addPattern(pattern); + collection.setName("deny-uncovered-http-methods"); + SecurityConstraint constraint = new SecurityConstraint(); + constraint.setAuthConstraint(true); + constraint.addCollection(collection); + addConstraint(constraint); + } else { + log.error(sm.getString( + "standardContext.uncoveredHttpOmittedMethod", + pattern, msg.toString().trim())); + } } } } Modified: tomcat/trunk/java/org/apache/catalina/deploy/WebXml.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/deploy/WebXml.java?rev=1494915&r1=1494914&r2=1494915&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/deploy/WebXml.java (original) +++ tomcat/trunk/java/org/apache/catalina/deploy/WebXml.java Thu Jun 20 10:38:49 2013 @@ -261,6 +261,15 @@ public class WebXml { this.distributable = distributable; } + // deny-uncovered-http-methods + private boolean denyUncoveredHttpMethods = false; + public boolean getDenyUncoveredHttpMethods() { + return denyUncoveredHttpMethods; + } + public void setDenyUncoveredHttpMethods(boolean denyUncoveredHttpMethods) { + this.denyUncoveredHttpMethods = denyUncoveredHttpMethods; + } + // context-param // TODO: description (multiple with language) is ignored private final Map<String,String> contextParams = new HashMap<>(); @@ -1267,6 +1276,17 @@ public class WebXml { displayName = temp.getDisplayName(); } + // Note: Not permitted in fragments but we also use fragments for + // per-Host and global defaults so it may appear there + if (!denyUncoveredHttpMethods) { + for (WebXml fragment : fragments) { + if (fragment.getDenyUncoveredHttpMethods()) { + denyUncoveredHttpMethods = true; + break; + } + } + } + if (distributable) { for (WebXml fragment : fragments) { if (!fragment.isDistributable()) { Modified: tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java?rev=1494915&r1=1494914&r2=1494915&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java (original) +++ tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java Thu Jun 20 10:38:49 2013 @@ -1279,6 +1279,8 @@ public class ContextConfig implements Li for (Entry<String, String> entry : webxml.getContextParams().entrySet()) { context.addParameter(entry.getKey(), entry.getValue()); } + context.setDenyUncoveredHttpMethods( + webxml.getDenyUncoveredHttpMethods()); context.setDisplayName(webxml.getDisplayName()); context.setDistributable(webxml.isDistributable()); for (ContextLocalEjb ejbLocalRef : webxml.getEjbLocalRefs().values()) { Modified: tomcat/trunk/java/org/apache/catalina/startup/FailedContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/FailedContext.java?rev=1494915&r1=1494914&r2=1494915&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/startup/FailedContext.java (original) +++ tomcat/trunk/java/org/apache/catalina/startup/FailedContext.java Thu Jun 20 10:38:49 2013 @@ -368,6 +368,13 @@ public class FailedContext extends Lifec public void setAltDDName(String altDDName) { /* NO-OP */ } @Override + public boolean getDenyUncoveredHttpMethods() { return false; } + @Override + public void setDenyUncoveredHttpMethods(boolean denyUncoveredHttpMethods) { + // NO-OP + } + + @Override public String getDisplayName() { return null; } @Override public void setDisplayName(String displayName) { /* NO-OP */ } Modified: tomcat/trunk/java/org/apache/catalina/startup/WebRuleSet.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/WebRuleSet.java?rev=1494915&r1=1494914&r2=1494915&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/startup/WebRuleSet.java (original) +++ tomcat/trunk/java/org/apache/catalina/startup/WebRuleSet.java Thu Jun 20 10:38:49 2013 @@ -203,6 +203,8 @@ public class WebRuleSet extends RuleSetB "addAbsoluteOrdering", 0); digester.addCallMethod(fullPrefix + "/absolute-ordering/others", "addAbsoluteOrderingOthers"); + digester.addRule(fullPrefix + "/deny-uncovered-http-methods", + new SetDenyUncoveredHttpMethodsRule()); } digester.addCallMethod(fullPrefix + "/context-param", @@ -803,9 +805,8 @@ final class SetAuthConstraintRule extend /** * Class that calls <code>setDistributable(true)</code> for the top object - * on the stack, which must be a <code>org.apache.catalina.Context</code>. + * on the stack, which must be a {@link WebXml} instance. */ - final class SetDistributableRule extends Rule { public SetDistributableRule() { @@ -822,7 +823,29 @@ final class SetDistributableRule extends (webXml.getClass().getName() + ".setDistributable(true)"); } } +} + + +/** + * Class that calls <code>setDenyUncoveredHttpMethods(true)</code> for the top + * object on the stack, which must be a {@link WebXml} instance. + */ +final class SetDenyUncoveredHttpMethodsRule extends Rule { + + public SetDenyUncoveredHttpMethodsRule() { + // NO-OP + } + @Override + public void begin(String namespace, String name, Attributes attributes) + throws Exception { + WebXml webXml = (WebXml) digester.peek(); + webXml.setDenyUncoveredHttpMethods(true); + if (digester.getLogger().isDebugEnabled()) { + digester.getLogger().debug(webXml.getClass().getName() + + ".setDenyUncoveredHttpMethods(true)"); + } + } } Modified: tomcat/trunk/test/org/apache/catalina/core/TesterContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/core/TesterContext.java?rev=1494915&r1=1494914&r2=1494915&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/catalina/core/TesterContext.java (original) +++ tomcat/trunk/test/org/apache/catalina/core/TesterContext.java Thu Jun 20 10:38:49 2013 @@ -455,6 +455,16 @@ public class TesterContext implements Co } @Override + public boolean getDenyUncoveredHttpMethods() { + return false; + } + + @Override + public void setDenyUncoveredHttpMethods(boolean denyUncoveredHttpMethods) { + // NO-OP + } + + @Override public String getDisplayName() { return null; } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org