You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2015/09/28 20:43:24 UTC

[6/8] struts git commit: Merges security fixes from 2.3.24.1

Merges security fixes from 2.3.24.1

Conflicts:
	apps/blank/pom.xml
	apps/jboss-blank/pom.xml
	apps/mailreader/pom.xml
	apps/pom.xml
	apps/portlet/pom.xml
	apps/rest-showcase/pom.xml
	apps/showcase/pom.xml
	archetypes/pom.xml
	archetypes/struts2-archetype-angularjs/pom.xml
	archetypes/struts2-archetype-blank/pom.xml
	archetypes/struts2-archetype-convention/pom.xml
	archetypes/struts2-archetype-dbportlet/pom.xml
	archetypes/struts2-archetype-plugin/pom.xml
	archetypes/struts2-archetype-portlet/pom.xml
	archetypes/struts2-archetype-starter/pom.xml
	assembly/pom.xml
	bom/pom.xml
	bundles/admin/pom.xml
	bundles/demo/pom.xml
	bundles/pom.xml
	core/pom.xml
	plugins/bean-validation/pom.xml
	plugins/cdi/pom.xml
	plugins/codebehind/pom.xml
	plugins/config-browser/pom.xml
	plugins/convention/pom.xml
	plugins/dojo/pom.xml
	plugins/dwr/pom.xml
	plugins/embeddedjsp/pom.xml
	plugins/gxp/pom.xml
	plugins/jasperreports/pom.xml
	plugins/java8-support/pom.xml
	plugins/javatemplates/pom.xml
	plugins/jfreechart/pom.xml
	plugins/json/pom.xml
	plugins/junit/pom.xml
	plugins/osgi/pom.xml
	plugins/oval/pom.xml
	plugins/pell-multipart/pom.xml
	plugins/plexus/pom.xml
	plugins/pom.xml
	plugins/portlet-tiles/pom.xml
	plugins/portlet/pom.xml
	plugins/rest/pom.xml
	plugins/sitegraph/pom.xml
	plugins/sitemesh/pom.xml
	plugins/spring/pom.xml
	plugins/struts1/pom.xml
	plugins/testng/pom.xml
	plugins/tiles/pom.xml
	plugins/tiles3/pom.xml
	pom.xml
	xwork-core/pom.xml


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/dc270c2e
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/dc270c2e
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/dc270c2e

Branch: refs/heads/master
Commit: dc270c2e09f944c9ed8936cb0a74cd2dfadacf81
Parents: 0fac539 bfe51fc
Author: Lukasz Lenart <lu...@apache.org>
Authored: Wed Sep 23 08:42:01 2015 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Wed Sep 23 08:42:01 2015 +0200

----------------------------------------------------------------------
 .../DefaultExcludedPatternsChecker.java         |  2 +-
 .../interceptor/ParametersInterceptorTest.java  |  6 ++--
 .../DefaultExcludedPatternsCheckerTest.java     | 35 ++++++++++++++++++++
 3 files changed, 40 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/dc270c2e/core/src/main/java/com/opensymphony/xwork2/security/DefaultExcludedPatternsChecker.java
----------------------------------------------------------------------
diff --cc core/src/main/java/com/opensymphony/xwork2/security/DefaultExcludedPatternsChecker.java
index f6d48cd,0000000..13e091e
mode 100644,000000..100644
--- a/core/src/main/java/com/opensymphony/xwork2/security/DefaultExcludedPatternsChecker.java
+++ b/core/src/main/java/com/opensymphony/xwork2/security/DefaultExcludedPatternsChecker.java
@@@ -1,77 -1,0 +1,77 @@@
 +package com.opensymphony.xwork2.security;
 +
 +import com.opensymphony.xwork2.XWorkConstants;
 +import com.opensymphony.xwork2.inject.Inject;
 +import com.opensymphony.xwork2.util.TextParseUtil;
 +import org.apache.logging.log4j.LogManager;
 +import org.apache.logging.log4j.Logger;
 +
 +import java.util.Arrays;
 +import java.util.HashSet;
 +import java.util.Set;
 +import java.util.regex.Pattern;
 +
 +public class DefaultExcludedPatternsChecker implements ExcludedPatternsChecker {
 +
 +    private static final Logger LOG = LogManager.getLogger(DefaultExcludedPatternsChecker.class);
 +
 +    public static final String[] EXCLUDED_PATTERNS = {
-         "(^|.*#)(dojo|struts|session|request|application|servlet(Request|Response)|parameters|context|_memberAccess)(\\.|\\[).*",
++        "(^|\\%\\{)((#?)(top(\\.|\\['|\\[\")|\\[\\d\\]\\.)?)(dojo|struts|session|request|response|application|servlet(Request|Response|Context)|parameters|context|_memberAccess)(\\.|\\[).*",
 +        "^(action|method):.*"
 +    };
 +
 +    private Set<Pattern> excludedPatterns;
 +
 +    public DefaultExcludedPatternsChecker() {
 +        setExcludedPatterns(EXCLUDED_PATTERNS);
 +    }
 +
 +    @Inject(value = XWorkConstants.OVERRIDE_EXCLUDED_PATTERNS, required = false)
 +    public void setOverrideExcludePatterns(String excludePatterns) {
 +        LOG.warn("Overriding excluded patterns [{}] with [{}], be aware that this affects all instances and safety of your application!",
 +                    XWorkConstants.OVERRIDE_EXCLUDED_PATTERNS, excludePatterns);
 +        excludedPatterns = new HashSet<Pattern>();
 +        for (String pattern : TextParseUtil.commaDelimitedStringToSet(excludePatterns)) {
 +            excludedPatterns.add(Pattern.compile(pattern, Pattern.CASE_INSENSITIVE));
 +        }
 +    }
 +
 +    @Inject(value = XWorkConstants.ADDITIONAL_EXCLUDED_PATTERNS, required = false)
 +    public void setAdditionalExcludePatterns(String excludePatterns) {
 +        LOG.debug("Adding additional global patterns [{}] to excluded patterns!", excludePatterns);
 +        for (String pattern : TextParseUtil.commaDelimitedStringToSet(excludePatterns)) {
 +            excludedPatterns.add(Pattern.compile(pattern, Pattern.CASE_INSENSITIVE));
 +        }
 +    }
 +
 +    public void setExcludedPatterns(String commaDelimitedPatterns) {
 +        setExcludedPatterns(TextParseUtil.commaDelimitedStringToSet(commaDelimitedPatterns));
 +    }
 +
 +    public void setExcludedPatterns(String[] patterns) {
 +        setExcludedPatterns(new HashSet<>(Arrays.asList(patterns)));
 +    }
 +
 +    public void setExcludedPatterns(Set<String> patterns) {
 +        LOG.trace("Sets excluded patterns [{}]", patterns);
 +        excludedPatterns = new HashSet<>(patterns.size());
 +        for (String pattern : patterns) {
 +            excludedPatterns.add(Pattern.compile(pattern, Pattern.CASE_INSENSITIVE));
 +        }
 +    }
 +
 +    public IsExcluded isExcluded(String value) {
 +        for (Pattern excludedPattern : excludedPatterns) {
 +            if (excludedPattern.matcher(value).matches()) {
 +                LOG.trace("[{}] matches excluded pattern [{}]", value, excludedPattern);
 +                return IsExcluded.yes(excludedPattern);
 +            }
 +        }
 +        return IsExcluded.no(excludedPatterns);
 +    }
 +
 +    public Set<Pattern> getExcludedPatterns() {
 +        return excludedPatterns;
 +    }
 +
 +}

http://git-wip-us.apache.org/repos/asf/struts/blob/dc270c2e/core/src/test/java/com/opensymphony/xwork2/interceptor/ParametersInterceptorTest.java
----------------------------------------------------------------------
diff --cc core/src/test/java/com/opensymphony/xwork2/interceptor/ParametersInterceptorTest.java
index abf0f72,0000000..225d053
mode 100644,000000..100644
--- a/core/src/test/java/com/opensymphony/xwork2/interceptor/ParametersInterceptorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/ParametersInterceptorTest.java
@@@ -1,856 -1,0 +1,858 @@@
 +/*
 + * Copyright 2002-2006,2009 The Apache Software Foundation.
 + * 
 + * Licensed under the Apache License, Version 2.0 (the "License");
 + * you may not use this file except in compliance with the License.
 + * You may obtain a copy of the License at
 + * 
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + * 
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +package com.opensymphony.xwork2.interceptor;
 +
 +import com.opensymphony.xwork2.*;
 +import com.opensymphony.xwork2.config.entities.ActionConfig;
 +import com.opensymphony.xwork2.config.providers.MockConfigurationProvider;
 +import com.opensymphony.xwork2.config.providers.XWorkConfigurationProvider;
 +import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
 +import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
 +import com.opensymphony.xwork2.mock.MockActionInvocation;
 +import com.opensymphony.xwork2.ognl.OgnlValueStack;
 +import com.opensymphony.xwork2.ognl.OgnlValueStackFactory;
 +import com.opensymphony.xwork2.ognl.SecurityMemberAccess;
 +import com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor;
 +import com.opensymphony.xwork2.util.CompoundRoot;
 +import com.opensymphony.xwork2.util.ValueStack;
 +import com.opensymphony.xwork2.util.ValueStackFactory;
 +import junit.framework.Assert;
 +import ognl.OgnlContext;
 +import ognl.PropertyAccessor;
 +
 +import java.io.File;
 +import java.util.*;
 +
 +
 +/**
 + * Unit test for {@link ParametersInterceptor}.
 + *
 + * @author Jason Carreira
 + */
 +public class ParametersInterceptorTest extends XWorkTestCase {
 +
 +    public void testParameterNameAware() {
 +        ParametersInterceptor pi = createParametersInterceptor();
 +        final Map<String, Object> actual = injectValueStackFactory(pi);
 +        ValueStack stack = createStubValueStack(actual);
 +        final Map<String, Object> expected = new HashMap<String, Object>() {
 +            {
 +                put("fooKey", "fooValue");
 +                put("barKey", "barValue");
 +            }
 +        };
 +        Object a = new ParameterNameAware() {
 +            public boolean acceptableParameterName(String parameterName) {
 +                return expected.containsKey(parameterName);
 +            }
 +        };
 +        final Map<String, Object> parameters = new HashMap<String, Object>() {
 +            {
 +                put("fooKey", "fooValue");
 +                put("barKey", "barValue");
 +                put("error-key", "error");
 +                put("error key", "error");
 +                put("error:key", "error");
 +                put("error+key", "error");
 +                put("test%test", "test%test");
 +            }
 +        };
 +        pi.setParameters(a, stack, parameters);
 +        assertEquals(expected, actual);
 +    }
 +
 +    public void testInsecureParameters() throws Exception {
 +        // given
 +        loadConfigurationProviders(new XWorkConfigurationProvider(), new XmlConfigurationProvider("xwork-param-test.xml"));
 +        final Map<String, Object> params = new HashMap<String, Object>() {
 +            {
 +                put("name", "(#context[\"xwork.MethodAccessor.denyMethodExecution\"]= new " +
 +                        "java.lang.Boolean(false), #_memberAccess[\"allowStaticMethodAccess\"]= new java.lang.Boolean(true), " +
 +                        "@java.lang.Runtime@getRuntime().exec('mkdir /tmp/PWNAGE'))(meh)");
 +                put("top['name'](0)", "true");
 +            }
 +        };
 +
 +        ParametersInterceptor pi = new ParametersInterceptor();
 +        container.inject(pi);
 +        ValueStack vs = ActionContext.getContext().getValueStack();
 +
 +        // when
 +        ValidateAction action = new ValidateAction();
 +        pi.setParameters(action, vs, params);
 +
 +        // then
-         assertEquals(1, action.getActionMessages().size());
++        assertEquals(2, action.getActionMessages().size());
 +
 +        String msg1 = action.getActionMessage(0);
++        String msg2 = action.getActionMessage(1);
 +
-         assertTrue(msg1.contains("Error setting expression 'top['name'](0)' with value 'true'"));
++        assertEquals("Error setting expression 'name' with value '(#context[\"xwork.MethodAccessor.denyMethodExecution\"]= new java.lang.Boolean(false), #_memberAccess[\"allowStaticMethodAccess\"]= new java.lang.Boolean(true), @java.lang.Runtime@getRuntime().exec('mkdir /tmp/PWNAGE'))(meh)'", msg1);
++        assertEquals("Error setting expression 'top['name'](0)' with value 'true'", msg2);
 +        assertNull(action.getName());
 +    }
 +
 +    public void testClassPollutionBlockedByPattern() throws Exception {
 +        // given
 +        final String pollution1 = "class.classLoader.jarPath";
 +        final String pollution2 = "model.class.classLoader.jarPath";
 +
 +        loadConfigurationProviders(new XWorkConfigurationProvider(), new XmlConfigurationProvider("xwork-param-test.xml"));
 +        final Map<String, Object> params = new HashMap<String, Object>() {
 +            {
 +                put(pollution1, "bad");
 +                put(pollution2, "very bad");
 +            }
 +        };
 +
 +        final Map<String, Boolean> excluded = new HashMap<>();
 +        ParametersInterceptor pi = new ParametersInterceptor() {
 +
 +            @Override
 +            protected boolean isExcluded(String paramName) {
 +                boolean result = super.isExcluded(paramName);
 +                excluded.put(paramName, result);
 +                return result;
 +            }
 +
 +        };
 +
 +        container.inject(pi);
 +        ValueStack vs = ActionContext.getContext().getValueStack();
 +
 +        // when
 +        ValidateAction action = new ValidateAction();
 +        pi.setParameters(action, vs, params);
 +
 +        // then
 +        assertEquals(0, action.getActionMessages().size());
 +        assertTrue(excluded.get(pollution1));
 +        assertTrue(excluded.get(pollution2));
 +    }
 +
 +    public void testClassPollutionBlockedByOgnl() throws Exception {
 +        // given
 +        final String pollution1 = "class.classLoader.jarPath";
 +        final String pollution2 = "model.class.classLoader.jarPath";
 +        final String pollution3 = "class.classLoader.defaultAssertionStatus";
 +
 +        loadConfigurationProviders(new XWorkConfigurationProvider(), new XmlConfigurationProvider("xwork-class-param-test.xml"));
 +        final Map<String, Object> params = new HashMap<String, Object>() {
 +            {
 +                put(pollution1, "bad");
 +                put(pollution2, "very bad");
 +                put(pollution3, true);
 +            }
 +        };
 +
 +        final Map<String, Boolean> excluded = new HashMap<>();
 +        ParametersInterceptor pi = new ParametersInterceptor() {
 +
 +            @Override
 +            protected boolean isExcluded(String paramName) {
 +                boolean result = super.isExcluded(paramName);
 +                excluded.put(paramName, result);
 +                return result;
 +            }
 +
 +        };
 +
 +        container.inject(pi);
 +        ValueStack vs = ActionContext.getContext().getValueStack();
 +
 +        // when
 +        ValidateAction action = new ValidateAction();
 +        pi.setParameters(action, vs, params);
 +
 +        // then
 +        assertEquals(3, action.getActionMessages().size());
 +
 +        String msg1 = action.getActionMessage(0);
 +        String msg2 = action.getActionMessage(1);
 +        String msg3 = action.getActionMessage(2);
 +
 +        assertEquals("Error setting expression 'class.classLoader.defaultAssertionStatus' with value 'true'", msg1);
 +        assertEquals("Error setting expression 'class.classLoader.jarPath' with value 'bad'", msg2);
 +        assertEquals("Error setting expression 'model.class.classLoader.jarPath' with value 'very bad'", msg3);
 +
 +        assertFalse(excluded.get(pollution1));
 +        assertFalse(excluded.get(pollution2));
 +        assertFalse(excluded.get(pollution3));
 +    }
 +
 +    public void testDoesNotAllowMethodInvocations() throws Exception {
 +        Map<String, Object> params = new HashMap<>();
 +        params.put("@java.lang.System@exit(1).dummy", "dumb value");
 +
 +        HashMap<String, Object> extraContext = new HashMap<>();
 +        extraContext.put(ActionContext.PARAMETERS, params);
 +
 +        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.MODEL_DRIVEN_PARAM_TEST, null, extraContext);
 +        assertEquals(Action.SUCCESS, proxy.execute());
 +
 +        String property = System.getProperty("xwork.security.test");
 +        assertNull(property);
 +    }
 +
 +    public void testModelDrivenParameters() throws Exception {
 +        Map<String, Object> params = new HashMap<>();
 +        final String fooVal = "com.opensymphony.xwork2.interceptor.ParametersInterceptorTest.foo";
 +        params.put("foo", fooVal);
 +
 +        final String nameVal = "com.opensymphony.xwork2.interceptor.ParametersInterceptorTest.name";
 +        params.put("name", nameVal);
 +        params.put("count", "15");
 +
 +        HashMap<String, Object> extraContext = new HashMap<>();
 +        extraContext.put(ActionContext.PARAMETERS, params);
 +
 +        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.MODEL_DRIVEN_PARAM_TEST, null, extraContext);
 +        assertEquals(Action.SUCCESS, proxy.execute());
 +
 +        ModelDrivenAction action = (ModelDrivenAction) proxy.getAction();
 +        TestBean model = (TestBean) action.getModel();
 +        assertEquals(nameVal, model.getName());
 +        assertEquals(15, model.getCount());
 +        assertEquals(fooVal, action.getFoo());
 +    }
 +
 +    public void testParametersDoesNotAffectSession() throws Exception {
 +        Map<String, Object> params = new HashMap<>();
 +        params.put("blah", "This is blah");
 +        params.put("#session.foo", "Foo");
 +        params.put("\u0023session[\'user\']", "0wn3d");
 +        params.put("\\u0023session[\'user\']", "0wn3d");
 +        params.put("\u0023session.user2", "0wn3d");
 +        params.put("\\u0023session.user2", "0wn3d");
 +        params.put("('\u0023'%20%2b%20'session[\'user3\']')(unused)", "0wn3d");
 +        params.put("('\\u0023' + 'session[\\'user4\\']')(unused)", "0wn3d");
 +        params.put("('\u0023'%2b'session[\'user5\']')(unused)", "0wn3d");
 +        params.put("('\\u0023'%2b'session[\'user5\']')(unused)", "0wn3d");
 +
 +        HashMap<String, Object> extraContext = new HashMap<>();
 +        extraContext.put(ActionContext.PARAMETERS, params);
 +
 +        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
 +        ValueStack stack = proxy.getInvocation().getStack();
 +        HashMap<String, Object> session = new HashMap<>();
 +        stack.getContext().put("session", session);
 +        proxy.execute();
 +        assertEquals("This is blah", ((SimpleAction) proxy.getAction()).getBlah());
 +        assertNull(session.get("foo"));
 +        assertNull(session.get("user"));
 +        assertNull(session.get("user2"));
 +        assertNull(session.get("user3"));
 +        assertNull(session.get("user4"));
 +        assertNull(session.get("user5"));
 +    }
 +
 +    public void testArrayClassPollutionBlockedByPattern() throws Exception {
 +        // given
 +        final String pollution1 = "model.class.classLoader.jarPath";
 +        final String pollution2 = "model['class']['classLoader']['jarPath']";
 +        final String pollution3 = "model[\"class\"]['classLoader']['jarPath']";
 +        final String pollution4 = "class.classLoader.jarPath";
 +        final String pollution5 = "class['classLoader']['jarPath']";
 +        final String pollution6 = "class[\"classLoader\"]['jarPath']";
 +
 +        loadConfigurationProviders(new XWorkConfigurationProvider(), new XmlConfigurationProvider("xwork-param-test.xml"));
 +        final Map<String, Object> params = new HashMap<String, Object>() {
 +            {
 +                put(pollution1, "bad");
 +                put(pollution2, "bad");
 +                put(pollution3, "bad");
 +                put(pollution4, "bad");
 +                put(pollution5, "bad");
 +                put(pollution6, "bad");
 +            }
 +        };
 +
 +        final Map<String, Boolean> excluded = new HashMap<String, Boolean>();
 +        ParametersInterceptor pi = new ParametersInterceptor() {
 +
 +            @Override
 +            protected boolean isExcluded(String paramName) {
 +                boolean result = super.isExcluded(paramName);
 +                excluded.put(paramName, result);
 +                return result;
 +            }
 +
 +        };
 +
 +        container.inject(pi);
 +        ValueStack vs = ActionContext.getContext().getValueStack();
 +
 +        // when
 +        ValidateAction action = new ValidateAction();
 +        pi.setParameters(action, vs, params);
 +
 +        // then
 +        assertEquals(0, action.getActionMessages().size());
 +        assertTrue(excluded.get(pollution1));
 +        assertTrue(excluded.get(pollution2));
 +        assertTrue(excluded.get(pollution3));
 +        assertTrue(excluded.get(pollution4));
 +        assertTrue(excluded.get(pollution5));
 +        assertTrue(excluded.get(pollution6));
 +    }
 +
 +    public void testAccessToOgnlInternals() throws Exception {
 +        // given
 +        Map<String, Object> params = new HashMap<>();
 +        params.put("blah", "This is blah");
 +        params.put("('\\u0023_memberAccess[\\'allowStaticMethodAccess\\']')(meh)", "true");
 +        params.put("('(aaa)(('\\u0023context[\\'xwork.MethodAccessor.denyMethodExecution\\']\\u003d\\u0023foo')(\\u0023foo\\u003dnew java.lang.Boolean(\"false\")))", "");
 +        params.put("(asdf)(('\\u0023rt.exit(1)')(\\u0023rt\\u003d@java.lang.Runtime@getRuntime()))", "1");
 +
 +        HashMap<String, Object> extraContext = new HashMap<>();
 +        extraContext.put(ActionContext.PARAMETERS, params);
 +
 +        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
 +        ValueStack stack = proxy.getInvocation().getStack();
 +
 +        // when
 +        proxy.execute();
 +        proxy.getAction();
 +
 +        //then
 +        assertEquals("This is blah", ((SimpleAction) proxy.getAction()).getBlah());
 +        boolean allowMethodAccess = ((SecurityMemberAccess) ((OgnlContext) stack.getContext()).getMemberAccess()).getAllowStaticMethodAccess();
 +        assertFalse(allowMethodAccess);
 +    }
 +
 +    public void testParameters() throws Exception {
 +        Map<String, Object> params = new HashMap<>();
 +        params.put("blah", "This is blah");
 +
 +        HashMap<String, Object> extraContext = new HashMap<>();
 +        extraContext.put(ActionContext.PARAMETERS, params);
 +
 +        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
 +        proxy.execute();
 +        assertEquals("This is blah", ((SimpleAction) proxy.getAction()).getBlah());
 +    }
 +
 +    public void testParametersWithSpacesInTheName() throws Exception {
 +        Map<String, Object> params = new HashMap<>();
 +        params.put("theProtectedMap['p0 p1']", "test1");
 +        params.put("theProtectedMap['p0p1 ']", "test2");
 +        params.put("theProtectedMap[' p0p1 ']", "test3");
 +        params.put("theProtectedMap[' p0 p1 ']", "test4");
 +
 +        HashMap<String, Object> extraContext = new HashMap<>();
 +        extraContext.put(ActionContext.PARAMETERS, params);
 +
 +        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
 +        proxy.execute();
 +        Map<String, String> existingMap = ((SimpleAction) proxy.getAction()).getTheProtectedMap();
 +        assertEquals(0, existingMap.size());
 +    }
 +
 +    public void testParametersWithChineseInTheName() throws Exception {
 +        Map<String, Object> params = new HashMap<>();
 +        params.put("theProtectedMap['名字']", "test1");
 +
 +        HashMap<String, Object> extraContext = new HashMap<>();
 +        extraContext.put(ActionContext.PARAMETERS, params);
 +
 +        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
 +        proxy.execute();
 +        Map<String, String> existingMap = ((SimpleAction) proxy.getAction()).getTheProtectedMap();
 +        assertEquals(1, existingMap.size());
 +    }
 +
 +    public void testLargeParameterNameWithDefaultLimit() throws Exception {
 +        ParametersInterceptor parametersInterceptor = createParametersInterceptor();
 +        doTestParameterNameLengthRestriction(parametersInterceptor, ParametersInterceptor.PARAM_NAME_MAX_LENGTH);
 +    }
 +
 +    public void testLargeParameterNameWithCustomLimit() throws Exception {
 +        ParametersInterceptor parametersInterceptor = createParametersInterceptor();
 +        int limit = 20;
 +        parametersInterceptor.setParamNameMaxLength(limit);
 +        doTestParameterNameLengthRestriction(parametersInterceptor, limit);
 +    }
 +
 +    private void doTestParameterNameLengthRestriction(ParametersInterceptor parametersInterceptor,
 +                                                      int paramNameMaxLength) {
 +        StringBuilder sb = new StringBuilder();
 +        for (int i = 0; i < paramNameMaxLength + 1; i++) {
 +            sb.append("x");
 +        }
 +
 +        Map<String, Object> actual = new LinkedHashMap<>();
 +        parametersInterceptor.setValueStackFactory(createValueStackFactory(actual));
 +        ValueStack stack = createStubValueStack(actual);
 +
 +        Map<String, Object> parameters = new HashMap<>();
 +        parameters.put(sb.toString(), "");
 +        parameters.put("huuhaa", "");
 +
 +        Action action = new SimpleAction();
 +        parametersInterceptor.setParameters(action, stack, parameters);
 +        assertEquals(1, actual.size());
 +    }
 +
 +    public void testExcludedTrickyParameters() throws Exception {
 +        Map<String, Object> params = new HashMap<String, Object>() {
 +            {
 +                put("blah", "This is blah");
 +                put("name", "try_1");
 +                put("(name)", "try_2");
 +                put("['name']", "try_3");
 +                put("['na' + 'me']", "try_4");
 +                put("{name}[0]", "try_5");
 +                put("(new string{'name'})[0]", "try_6");
 +                put("#{key: 'name'}.key", "try_7");
 +
 +            }
 +        };
 +
 +        HashMap<String, Object> extraContext = new HashMap<>();
 +        extraContext.put(ActionContext.PARAMETERS, params);
 +
 +        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
 +
 +        ActionConfig config = configuration.getRuntimeConfiguration().getActionConfig("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME);
 +        ParametersInterceptor pi = (ParametersInterceptor) config.getInterceptors().get(0).getInterceptor();
 +        pi.setExcludeParams("name");
 +
 +        proxy.execute();
 +
 +        SimpleAction action = (SimpleAction) proxy.getAction();
 +        assertNull(action.getName());
 +        assertEquals("This is blah", (action).getBlah());
 +    }
 +
 +    public void testAcceptedTrickyParameters() throws Exception {
 +        Map<String, Object> params = new HashMap<String, Object>() {
 +            {
 +                put("blah", "This is blah");
 +                put("baz", "123");
 +                put("name", "try_1");
 +                put("(name)", "try_2");
 +                put("['name']", "try_3");
 +                put("['na' + 'me']", "try_4");
 +                put("{name}[0]", "try_5");
 +                put("(new string{'name'})[0]", "try_6");
 +                put("#{key: 'name'}.key", "try_7");
 +            }
 +        };
 +
 +        HashMap<String, Object> extraContext = new HashMap<>();
 +        extraContext.put(ActionContext.PARAMETERS, params);
 +
 +        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
 +
 +        ActionConfig config = configuration.getRuntimeConfiguration().getActionConfig("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME);
 +        ParametersInterceptor pi = (ParametersInterceptor) config.getInterceptors().get(0).getInterceptor();
 +        pi.setAcceptParamNames("blah, baz");
 +
 +        proxy.execute();
 +
 +        SimpleAction action = (SimpleAction) proxy.getAction();
 +        assertNull("try_1", action.getName());
 +        assertEquals("This is blah", (action).getBlah());
 +        assertEquals(123, action.getBaz());
 +    }
 +
 +
 +    public void testParametersNotAccessPrivateVariables() throws Exception {
 +        Map<String, Object> params = new HashMap<>();
 +        params.put("protectedMap.foo", "This is blah");
 +        params.put("theProtectedMap.boo", "This is blah");
 +
 +        HashMap<String, Object> extraContext = new HashMap<>();
 +        extraContext.put(ActionContext.PARAMETERS, params);
 +
 +        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
 +        proxy.execute();
 +        SimpleAction action = (SimpleAction) proxy.getAction();
 +        assertEquals(1, action.getTheProtectedMap().size());
 +        assertNotNull(action.getTheProtectedMap().get("boo"));
 +        assertNull(action.getTheProtectedMap().get("foo"));
 +    }
 +
 +    public void testParametersNotAccessProtectedMethods() throws Exception {
 +        Map<String, Object> params = new HashMap<>();
 +        params.put("theSemiProtectedMap.foo", "This is blah");
 +        params.put("theProtectedMap.boo", "This is blah");
 +
 +        HashMap<String, Object> extraContext = new HashMap<>();
 +        extraContext.put(ActionContext.PARAMETERS, params);
 +
 +        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
 +        proxy.execute();
 +        SimpleAction action = (SimpleAction) proxy.getAction();
 +        assertEquals(1, action.getTheProtectedMap().size());
 +        assertNotNull(action.getTheProtectedMap().get("boo"));
 +        assertNull(action.getTheProtectedMap().get("foo"));
 +    }
 +
 +    /**
 +     * This test demonstrates a vulnerability which allows to execute arbitrary code.
 +     * For further details and explanations see https://cwiki.apache.org/confluence/display/WW/S2-009
 +     *
 +     * @throws Exception
 +     */
 +    public void testEvalExpressionAsParameterName() throws Exception {
 +        Map<String, Object> params = new HashMap<>();
 +        params.put("blah", "(#context[\"xwork.MethodAccessor.denyMethodExecution\"]= new " +
 +                "java.lang.Boolean(false), #_memberAccess[\"allowStaticMethodAccess\"]= new java.lang.Boolean(true), " +
 +                "@java.lang.Runtime@getRuntime().exec('mkdir /tmp/PWNAGE'))(meh)");
 +        params.put("top['blah'](0)", "true");
 +
 +        HashMap<String, Object> extraContext = new HashMap<>();
 +        extraContext.put(ActionContext.PARAMETERS, params);
 +
 +        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
 +        proxy.execute();
 +        @SuppressWarnings("unused")
 +        SimpleAction action = (SimpleAction) proxy.getAction();
 +        File pwn = new File("/tmp/PWNAGE");
 +        boolean dirExists = pwn.exists();
 +        @SuppressWarnings("unused")
 +        boolean deleted = pwn.delete();
 +        Assert.assertFalse("Remote exploit: The PWN folder has been created", dirExists);
 +    }
 +
 +    public void testParametersOverwriteField() throws Exception {
 +        Map<String, Object> params = new LinkedHashMap<>();
 +        params.put("existingMap.boo", "This is blah");
 +
 +        HashMap<String, Object> extraContext = new HashMap<>();
 +        extraContext.put(ActionContext.PARAMETERS, params);
 +
 +        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
 +        proxy.execute();
 +        SimpleAction action = (SimpleAction) proxy.getAction();
 +        assertEquals(1, action.getTheExistingMap().size());
 +        assertNotNull(action.getTheExistingMap().get("boo"));
 +        assertNull(action.getTheExistingMap().get("existingKey"));
 +    }
 +
 +    public void testNonexistentParametersGetLoggedInDevMode() throws Exception {
 +        XmlConfigurationProvider provider = new XmlConfigurationProvider("xwork-test-beans.xml");
 +        container.inject(provider);
 +        loadConfigurationProviders(provider,
 +                new MockConfigurationProvider(Collections.singletonMap("devMode", "true")));
 +        Map<String, Object> params = new HashMap<>();
 +        params.put("not_a_property", "There is no action property named like this");
 +
 +        HashMap<String, Object> extraContext = new HashMap<>();
 +        extraContext.put(ActionContext.PARAMETERS, params);
 +
 +        ActionConfig config = configuration.getRuntimeConfiguration().getActionConfig("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME);
 +        container.inject(config.getInterceptors().get(0).getInterceptor());
 +        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
 +        proxy.execute();
 +        final String actionMessage = "" + ((SimpleAction) proxy.getAction()).getActionMessages().toArray()[0];
 +        assertTrue(actionMessage.contains("Error setting expression 'not_a_property' with value 'There is no action property named like this'"));
 +    }
 +
 +    public void testNonexistentParametersAreIgnoredInProductionMode() throws Exception {
 +        XmlConfigurationProvider provider = new XmlConfigurationProvider("xwork-test-beans.xml");
 +        container.inject(provider);
 +        loadConfigurationProviders(provider,
 +                new MockConfigurationProvider(Collections.singletonMap("devMode", "false")));
 +        Map<String, Object> params = new HashMap<>();
 +        params.put("not_a_property", "There is no action property named like this");
 +
 +        HashMap<String, Object> extraContext = new HashMap<>();
 +        extraContext.put(ActionContext.PARAMETERS, params);
 +
 +        ActionConfig config = configuration.getRuntimeConfiguration().getActionConfig("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME);
 +        container.inject(config.getInterceptors().get(0).getInterceptor());
 +        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
 +        proxy.execute();
 +        assertTrue(((SimpleAction) proxy.getAction()).getActionMessages().isEmpty());
 +    }
 +
 +    public void testNoParametersAction() throws Exception {
 +        ParametersInterceptor interceptor = new ParametersInterceptor();
 +        interceptor.init();
 +
 +        MockActionInvocation mai = new MockActionInvocation();
 +        Action action = new NoParametersAction();
 +        mai.setAction(action);
 +
 +        interceptor.doIntercept(mai);
 +        interceptor.destroy();
 +    }
 +
 +    public void testNoOrdered() throws Exception {
 +        ParametersInterceptor pi = createParametersInterceptor();
 +        final Map<String, Object> actual = new LinkedHashMap<>();
 +        pi.setValueStackFactory(createValueStackFactory(actual));
 +        ValueStack stack = createStubValueStack(actual);
 +
 +        Map<String, Object> parameters = new HashMap<>();
 +        parameters.put("user.address.city", "London");
 +        parameters.put("user.name", "Superman");
 +
 +        Action action = new SimpleAction();
 +        pi.setParameters(action, stack, parameters);
 +
 +        assertEquals("ordered should be false by default", false, pi.isOrdered());
 +        assertEquals(2, actual.size());
 +        assertEquals("London", actual.get("user.address.city"));
 +        assertEquals("Superman", actual.get("user.name"));
 +
 +        // is not ordered
 +        List<Object> values = new ArrayList<Object>(actual.values());
 +        assertEquals("London", values.get(0));
 +        assertEquals("Superman", values.get(1));
 +    }
 +
 +    public void testOrdered() throws Exception {
 +        ParametersInterceptor pi = new ParametersInterceptor();
 +        pi.setOrdered(true);
 +        container.inject(pi);
 +        final Map<String, Object> actual = new LinkedHashMap<>();
 +        pi.setValueStackFactory(createValueStackFactory(actual));
 +        ValueStack stack = createStubValueStack(actual);
 +
 +        Map<String, Object> parameters = new HashMap<>();
 +        parameters.put("user.address.city", "London");
 +        parameters.put("user.address['postal']", "QJR387");
 +        parameters.put("user.name", "Superman");
 +
 +        Action action = new SimpleAction();
 +        pi.setParameters(action, stack, parameters);
 +
 +        assertEquals(true, pi.isOrdered());
 +        assertEquals(3, actual.size());
 +        assertEquals("London", actual.get("user.address.city"));
 +        assertEquals("QJR387", actual.get("user.address['postal']"));
 +        assertEquals("Superman", actual.get("user.name"));
 +
 +        // should be ordered so user.name should be first
 +        List<Object> values = new ArrayList<Object>(actual.values());
 +        assertEquals("Superman", values.get(0));
 +        assertEquals("London", values.get(1));
 +        assertEquals("QJR387", values.get(2));
 +    }
 +
 +    public void testSetOrdered() throws Exception {
 +        ParametersInterceptor pi = createParametersInterceptor();
 +        assertEquals("ordered should be false by default", false, pi.isOrdered());
 +        pi.setOrdered(true);
 +        assertEquals(true, pi.isOrdered());
 +    }
 +
 +    public void testExcludedParametersAreIgnored() throws Exception {
 +        ParametersInterceptor pi = createParametersInterceptor();
 +        pi.setExcludeParams("dojo\\..*");
 +        final Map<String, Object> actual = injectValueStackFactory(pi);
 +        ValueStack stack = injectValueStack(actual);
 +
 +        final Map<String, Object> expected = new HashMap<String, Object>() {
 +            {
 +                put("fooKey", "fooValue");
 +            }
 +        };
 +
 +        Map<String, Object> parameters = new HashMap<String, Object>() {
 +            {
 +                put("dojo.test", "dojoValue");
 +                put("fooKey", "fooValue");
 +            }
 +        };
 +        pi.setParameters(new NoParametersAction(), stack, parameters);
 +        assertEquals(expected, actual);
 +    }
 +
 +    public void testInternalParametersAreIgnored() throws Exception {
 +        // given
 +        ParametersInterceptor interceptor = createParametersInterceptor();
 +        final Map<String, Object> actual = injectValueStackFactory(interceptor);
 +        ValueStack stack = injectValueStack(actual);
 +
 +
 +        final Map<String, Object> expected = new HashMap<String, Object>() {
 +            {
 +                put("ordinary.bean", "value");
 +            }
 +        };
 +
 +        Map<String, Object> parameters = new HashMap<String, Object>() {
 +            {
 +                put("ordinary.bean", "value");
 +                put("#some.internal.object", "true");
 +                put("(bla)#some.internal.object", "true");
 +                put("#some.internal.object(bla)#some.internal.object", "true");
 +                put("#_some.internal.object", "true");
 +                put("\u0023_some.internal.object", "true");
 +                put("\u0023_some.internal.object,[dfd],bla(\u0023_some.internal.object)", "true");
 +                put("\\u0023_some.internal.object", "true");
 +            }
 +        };
 +
 +        // when
 +        interceptor.setParameters(new NoParametersAction(), stack, parameters);
 +
 +        // then
 +        assertEquals(expected, actual);
 +    }
 +
 +    private ValueStack injectValueStack(Map<String, Object> actual) {
 +        ValueStack stack = createStubValueStack(actual);
 +        container.inject(stack);
 +        return stack;
 +    }
 +
 +    private Map<String, Object> injectValueStackFactory(ParametersInterceptor interceptor) {
 +        final Map<String, Object> actual = new HashMap<>();
 +        interceptor.setValueStackFactory(createValueStackFactory(actual));
 +        return actual;
 +    }
 +
 +    private ParametersInterceptor createParametersInterceptor() {
 +        ParametersInterceptor pi = new ParametersInterceptor();
 +        container.inject(pi);
 +        return pi;
 +    }
 +
 +    private ValueStackFactory createValueStackFactory(final Map<String, Object> context) {
 +        OgnlValueStackFactory factory = new OgnlValueStackFactory() {
 +            @Override
 +            public ValueStack createValueStack(ValueStack stack) {
 +                return createStubValueStack(context);
 +            }
 +        };
 +        container.inject(factory);
 +        return factory;
 +    }
 +
 +    private ValueStack createStubValueStack(final Map<String, Object> actual) {
 +        ValueStack stack = new OgnlValueStack(
 +                container.getInstance(XWorkConverter.class),
 +                (CompoundRootAccessor) container.getInstance(PropertyAccessor.class, CompoundRoot.class.getName()),
 +                container.getInstance(TextProvider.class, "system"), true) {
 +            @Override
 +            public void setValue(String expr, Object value) {
 +                actual.put(expr, value);
 +            }
 +
 +            @Override
 +            public void setParameter(String expr, Object value) {
 +                actual.put(expr, value);
 +            }
 +        };
 +        container.inject(stack);
 +        return stack;
 +    }
 +
 +    /*
 +    public void testIndexedParameters() throws Exception {
 +        Map params = new HashMap();
 +        params.put("indexedProp[33]", "This is blah");
 +
 +        HashMap extraContext = new HashMap();
 +        extraContext.put(ActionContext.PARAMETERS, params);
 +
 +        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, extraContext);
 +        proxy.execute();
 +        assertEquals("This is blah", ((SimpleAction) proxy.getAction()).getIndexedProp(33));
 +    }
 +    */
 +
 +
 +    private class NoParametersAction implements Action, NoParameters {
 +
 +        public String execute() throws Exception {
 +            return SUCCESS;
 +        }
 +    }
 +
 +    @Override
 +    protected void setUp() throws Exception {
 +        super.setUp();
 +        XmlConfigurationProvider provider = new XmlConfigurationProvider("xwork-test-beans.xml");
 +        container.inject(provider);
 +        loadConfigurationProviders(provider, new MockConfigurationProvider());
 +
 +        ActionConfig config = configuration.getRuntimeConfiguration().getActionConfig("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME);
 +        container.inject(config.getInterceptors().get(0).getInterceptor());
 +    }
 +
 +}
 +
 +class ValidateAction implements ValidationAware {
 +
 +    private List<String> messages = new LinkedList<>();
 +    private String name;
 +
 +    public void setActionErrors(Collection<String> errorMessages) {
 +    }
 +
 +    public Collection<String> getActionErrors() {
 +        return null;
 +    }
 +
 +    public void setActionMessages(Collection<String> messages) {
 +    }
 +
 +    public Collection<String> getActionMessages() {
 +        return messages;
 +    }
 +
 +    public void setFieldErrors(Map<String, List<String>> errorMap) {
 +    }
 +
 +    public Map<String, List<String>> getFieldErrors() {
 +        return null;
 +    }
 +
 +    public void addActionError(String anErrorMessage) {
 +    }
 +
 +    public void addActionMessage(String aMessage) {
 +        messages.add(aMessage);
 +    }
 +
 +    public void addFieldError(String fieldName, String errorMessage) {
 +    }
 +
 +    public boolean hasActionErrors() {
 +        return false;
 +    }
 +
 +    public boolean hasActionMessages() {
 +        return messages.size() > 0;
 +    }
 +
 +    public boolean hasErrors() {
 +        return false;
 +    }
 +
 +    public boolean hasFieldErrors() {
 +        return false;
 +    }
 +
 +    public String getActionMessage(int index) {
 +        return messages.get(index);
 +    }
 +
 +    public String getName() {
 +        return name;
 +    }
 +
 +    public void setName(String name) {
 +        this.name = name;
 +    }
 +
 +}

http://git-wip-us.apache.org/repos/asf/struts/blob/dc270c2e/core/src/test/java/com/opensymphony/xwork2/security/DefaultExcludedPatternsCheckerTest.java
----------------------------------------------------------------------
diff --cc core/src/test/java/com/opensymphony/xwork2/security/DefaultExcludedPatternsCheckerTest.java
index 367e199,0000000..faf807e
mode 100644,000000..100644
--- a/core/src/test/java/com/opensymphony/xwork2/security/DefaultExcludedPatternsCheckerTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/security/DefaultExcludedPatternsCheckerTest.java
@@@ -1,106 -1,0 +1,141 @@@
 +package com.opensymphony.xwork2.security;
 +
 +import com.opensymphony.xwork2.XWorkTestCase;
 +
 +import java.util.ArrayList;
++import java.util.Arrays;
 +import java.util.List;
 +
 +public class DefaultExcludedPatternsCheckerTest extends XWorkTestCase {
 +
 +    public void testHardcodedPatterns() throws Exception {
 +        // given
 +        List<String> params = new ArrayList<String>() {
 +            {
 +                add("%{#application['test']}");
 +                add("%{#application.test}");
 +                add("%{#Application['test']}");
 +                add("%{#Application.test}");
 +                add("%{#session['test']}");
 +                add("%{#session.test}");
 +                add("%{#Session['test']}");
 +                add("%{#Session.test}");
 +                add("%{#struts['test']}");
 +                add("%{#struts.test}");
 +                add("%{#Struts['test']}");
 +                add("%{#Struts.test}");
 +                add("%{#request['test']}");
 +                add("%{#request.test}");
 +                add("%{#Request['test']}");
 +                add("%{#Request.test}");
 +                add("%{#servletRequest['test']}");
 +                add("%{#servletRequest.test}");
 +                add("%{#ServletRequest['test']}");
 +                add("%{#ServletRequest.test}");
 +                add("%{#servletResponse['test']}");
 +                add("%{#servletResponse.test}");
 +                add("%{#ServletResponse['test']}");
 +                add("%{#ServletResponse.test}");
++                add("%{#servletContext['test']}");
++                add("%{#servletContext.test}");
++                add("%{#ServletContext['test']}");
++                add("%{#ServletContext.test}");
 +                add("%{#parameters['test']}");
 +                add("%{#parameters.test}");
 +                add("%{#Parameters['test']}");
 +                add("%{#Parameters.test}");
 +                add("#context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse')");
 +                add("%{#context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse')}");
 +                add("#_memberAccess[\"allowStaticMethodAccess\"]= new java.lang.Boolean(true)");
 +                add("%{#_memberAccess[\"allowStaticMethodAccess\"]= new java.lang.Boolean(true)}");
 +                add("form.class.classLoader");
 +                add("form[\"class\"][\"classLoader\"]");
 +                add("form['class']['classLoader']");
 +                add("class['classLoader']");
 +                add("class[\"classLoader\"]");
 +                add("class.classLoader.resources.dirContext.docBase=tttt");
 +                add("Class.classLoader.resources.dirContext.docBase=tttt");
 +            }
 +        };
 +
 +        DefaultExcludedPatternsChecker checker = new DefaultExcludedPatternsChecker();
 +        checker.setAdditionalExcludePatterns(".*(^|\\.|\\[|'|\")class(\\.|\\[|'|\").*");
 +
 +        for (String param : params) {
 +            // when
 +            ExcludedPatternsChecker.IsExcluded actual = checker.isExcluded(param);
 +
 +            // then
 +            assertTrue("Access to " + param + " is possible!", actual.isExcluded());
 +        }
 +    }
 +
++    public void testDefaultExcludePatterns() throws Exception {
++        // given
++        List<String> prefixes = Arrays.asList("#[0].%s", "[0].%s", "top.%s", "%{[0].%s}", "%{#[0].%s}", "%{top.%s}", "%{#top.%s}", "%{#%s}", "%{%s}", "#%s");
++        List<String> inners = Arrays.asList("servletRequest", "servletResponse", "servletContext", "application", "session", "struts", "request", "response", "dojo", "parameters");
++        List<String> suffixes = Arrays.asList("['test']", "[\"test\"]", ".test");
++
++        DefaultExcludedPatternsChecker checker = new DefaultExcludedPatternsChecker();
++        checker.setAdditionalExcludePatterns(".*(^|\\.|\\[|'|\")class(\\.|\\[|'|\").*");
++
++        List<String> params = new ArrayList<String>();
++        for (String prefix : prefixes) {
++            for (String inner : inners) {
++                String innerUp = inner.substring(0, 1).toUpperCase() + inner.substring(1);
++                for (String suffix : suffixes) {
++                    params.add(prefix.replace("%s", inner + suffix));
++                    params.add(prefix.replace("%s", innerUp + suffix));
++                }
++            }
++        }
++
++        for (String param : params) {
++            System.out.println(param);
++            // when
++            ExcludedPatternsChecker.IsExcluded actual = checker.isExcluded(param);
++
++            // then
++            assertTrue("Access to " + param + " is possible!", actual.isExcluded());
++        }
++    }
++
 +    public void testParamWithClassInName() throws Exception {
 +        // given
 +        List<String> properParams = new ArrayList<>();
 +        properParams.add("eventClass");
 +        properParams.add("form.eventClass");
 +        properParams.add("form[\"eventClass\"]");
 +        properParams.add("form['eventClass']");
 +        properParams.add("class.super@demo.com");
 +        properParams.add("super.class@demo.com");
 +
 +        ExcludedPatternsChecker checker = new DefaultExcludedPatternsChecker();
 +
 +        for (String properParam : properParams) {
 +            // when
 +            ExcludedPatternsChecker.IsExcluded actual = checker.isExcluded(properParam);
 +
 +            // then
 +            assertFalse("Param '" + properParam + "' is excluded!", actual.isExcluded());
 +        }
 +    }
 +
 +    public void testStrutsTokenIsExcluded() throws Exception {
 +        // given
 +        List<String> tokens = new ArrayList<>();
 +        tokens.add("struts.token.name");
 +        tokens.add("struts.token");
 +
 +        ExcludedPatternsChecker checker = new DefaultExcludedPatternsChecker();
 +
 +        for (String token : tokens) {
 +            // when
 +            ExcludedPatternsChecker.IsExcluded actual = checker.isExcluded(token);
 +
 +            // then
 +            assertTrue("Param '" + token + "' is not excluded!", actual.isExcluded());
 +        }
 +    }
 +
 +}