diff --git a/apps/blank/pom.xml b/apps/blank/pom.xml index 675de3fa9c..190b21e33d 100644 --- a/apps/blank/pom.xml +++ b/apps/blank/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-apps - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-blank diff --git a/apps/jboss-blank/pom.xml b/apps/jboss-blank/pom.xml index 3335999783..e321ab8c7f 100644 --- a/apps/jboss-blank/pom.xml +++ b/apps/jboss-blank/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-apps - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-jboss-blank diff --git a/apps/mailreader/pom.xml b/apps/mailreader/pom.xml index 7275fdf3b8..6e4e5d56e0 100644 --- a/apps/mailreader/pom.xml +++ b/apps/mailreader/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-apps - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-mailreader diff --git a/apps/pom.xml b/apps/pom.xml index 94771b4f7c..ac067536b6 100644 --- a/apps/pom.xml +++ b/apps/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-parent - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-apps pom diff --git a/apps/portlet/pom.xml b/apps/portlet/pom.xml index 3a87ebbed4..86d49585fb 100644 --- a/apps/portlet/pom.xml +++ b/apps/portlet/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-apps - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-portlet diff --git a/apps/rest-showcase/pom.xml b/apps/rest-showcase/pom.xml index 4d9507ec3e..270f5e6359 100644 --- a/apps/rest-showcase/pom.xml +++ b/apps/rest-showcase/pom.xml @@ -26,12 +26,12 @@ org.apache.struts struts2-apps - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-rest-showcase war - 2.3.18-SNAPSHOT + 2.3.16.2 Struts 2 Rest Showcase Webapp Struts 2 Rest Showcase Example diff --git a/apps/showcase/pom.xml b/apps/showcase/pom.xml index ef100077d2..7e6d28d190 100644 --- a/apps/showcase/pom.xml +++ b/apps/showcase/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-apps - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-showcase diff --git a/archetypes/pom.xml b/archetypes/pom.xml index cad40b9df3..5ea2556635 100644 --- a/archetypes/pom.xml +++ b/archetypes/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-parent - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-archetypes diff --git a/archetypes/struts2-archetype-angularjs/pom.xml b/archetypes/struts2-archetype-angularjs/pom.xml index 5d6d4ab7ed..4adf8b465e 100644 --- a/archetypes/struts2-archetype-angularjs/pom.xml +++ b/archetypes/struts2-archetype-angularjs/pom.xml @@ -2,7 +2,7 @@ org.apache.struts struts2-archetypes - 2.3.18-SNAPSHOT + 2.3.16.2 4.0.0 diff --git a/archetypes/struts2-archetype-blank/pom.xml b/archetypes/struts2-archetype-blank/pom.xml index a9e0d1a20d..27f935111b 100644 --- a/archetypes/struts2-archetype-blank/pom.xml +++ b/archetypes/struts2-archetype-blank/pom.xml @@ -3,7 +3,7 @@ org.apache.struts struts2-archetypes - 2.3.18-SNAPSHOT + 2.3.16.2 4.0.0 diff --git a/archetypes/struts2-archetype-convention/pom.xml b/archetypes/struts2-archetype-convention/pom.xml index da7e8cb342..17a912cddb 100644 --- a/archetypes/struts2-archetype-convention/pom.xml +++ b/archetypes/struts2-archetype-convention/pom.xml @@ -2,7 +2,7 @@ org.apache.struts struts2-archetypes - 2.3.18-SNAPSHOT + 2.3.16.2 4.0.0 diff --git a/archetypes/struts2-archetype-dbportlet/pom.xml b/archetypes/struts2-archetype-dbportlet/pom.xml index bd1744442a..da8f1b8dfe 100644 --- a/archetypes/struts2-archetype-dbportlet/pom.xml +++ b/archetypes/struts2-archetype-dbportlet/pom.xml @@ -2,7 +2,7 @@ org.apache.struts struts2-archetypes - 2.3.18-SNAPSHOT + 2.3.16.2 4.0.0 diff --git a/archetypes/struts2-archetype-plugin/pom.xml b/archetypes/struts2-archetype-plugin/pom.xml index 05ee3dea93..24f1a3d402 100644 --- a/archetypes/struts2-archetype-plugin/pom.xml +++ b/archetypes/struts2-archetype-plugin/pom.xml @@ -2,7 +2,7 @@ org.apache.struts struts2-archetypes - 2.3.18-SNAPSHOT + 2.3.16.2 4.0.0 diff --git a/archetypes/struts2-archetype-portlet/pom.xml b/archetypes/struts2-archetype-portlet/pom.xml index 552556892e..c8a6f64c5e 100644 --- a/archetypes/struts2-archetype-portlet/pom.xml +++ b/archetypes/struts2-archetype-portlet/pom.xml @@ -2,7 +2,7 @@ org.apache.struts struts2-archetypes - 2.3.18-SNAPSHOT + 2.3.16.2 4.0.0 diff --git a/archetypes/struts2-archetype-starter/pom.xml b/archetypes/struts2-archetype-starter/pom.xml index c642510e25..1e533a857e 100644 --- a/archetypes/struts2-archetype-starter/pom.xml +++ b/archetypes/struts2-archetype-starter/pom.xml @@ -4,7 +4,7 @@ org.apache.struts struts2-archetypes - 2.3.18-SNAPSHOT + 2.3.16.2 4.0.0 diff --git a/assembly/pom.xml b/assembly/pom.xml index 6028a14f0c..56a551b2d6 100644 --- a/assembly/pom.xml +++ b/assembly/pom.xml @@ -3,7 +3,7 @@ org.apache.struts struts2-parent - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-assembly diff --git a/bundles/admin/pom.xml b/bundles/admin/pom.xml index ddc8cdf06a..e9fdc78087 100644 --- a/bundles/admin/pom.xml +++ b/bundles/admin/pom.xml @@ -4,7 +4,7 @@ org.apache.struts struts2-osgi-bundles - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-osgi-admin-bundle diff --git a/bundles/demo/pom.xml b/bundles/demo/pom.xml index f0bd5adb50..a8613a3ead 100644 --- a/bundles/demo/pom.xml +++ b/bundles/demo/pom.xml @@ -4,7 +4,7 @@ org.apache.struts struts2-osgi-bundles - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-osgi-demo-bundle diff --git a/bundles/pom.xml b/bundles/pom.xml index e40fe1c96f..b86c91fc1f 100755 --- a/bundles/pom.xml +++ b/bundles/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-parent - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-osgi-bundles diff --git a/core/pom.xml b/core/pom.xml index d9527f2c5e..02aee40f1c 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-parent - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-core jar diff --git a/core/src/main/java/org/apache/struts2/interceptor/CookieInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/CookieInterceptor.java index 939956c001..3e2e81d321 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/CookieInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/CookieInterceptor.java @@ -24,6 +24,7 @@ import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; +import com.opensymphony.xwork2.ExcludedPatterns; import com.opensymphony.xwork2.util.TextParseUtil; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.logging.Logger; @@ -173,7 +174,8 @@ public class CookieInterceptor extends AbstractInterceptor { private Set cookiesValueSet = Collections.emptySet(); // Allowed names of cookies - private Pattern acceptedPattern = Pattern.compile(ACCEPTED_PATTERN); + private Pattern acceptedPattern = Pattern.compile(ACCEPTED_PATTERN, Pattern.CASE_INSENSITIVE); + private Pattern excludedPattern = Pattern.compile(ExcludedPatterns.CLASS_ACCESS_PATTERN, Pattern.CASE_INSENSITIVE); /** * Set the cookiesName which if matched will allow the cookie @@ -223,7 +225,7 @@ public String intercept(ActionInvocation invocation) throws Exception { String name = cookie.getName(); String value = cookie.getValue(); - if (acceptedPattern.matcher(name).matches()) { + if (isAcceptableName(name) && isAcceptableValue(value)) { if (cookiesNameSet.contains("*")) { if (LOG.isDebugEnabled()) { LOG.debug("contains cookie name [*] in configured cookies name set, cookie with name [" + name + "] with value [" + value + "] will be injected"); @@ -233,7 +235,7 @@ public String intercept(ActionInvocation invocation) throws Exception { populateCookieValueIntoStack(name, value, cookiesMap, stack); } } else { - LOG.warn("Cookie name [" + name + "] does not match accepted cookie names pattern [" + acceptedPattern + "]"); + LOG.warn("Cookie name [#0] with value [#1] was rejected!", name, value); } } } @@ -244,6 +246,72 @@ public String intercept(ActionInvocation invocation) throws Exception { return invocation.invoke(); } + /** + * Checks if value of Cookie doesn't contain vulnerable code + * + * @param value of Cookie + * @return true|false + */ + protected boolean isAcceptableValue(String value) { + boolean matches = !excludedPattern.matcher(value).matches(); + if (!matches) { + if (LOG.isTraceEnabled()) { + LOG.trace("Cookie value [#0] matches excludedPattern [#1]", value, ExcludedPatterns.CLASS_ACCESS_PATTERN); + } + } + return matches; + } + + /** + * Checks if name of Cookie doesn't contain vulnerable code + * + * @param name of Cookie + * @return true|false + */ + protected boolean isAcceptableName(String name) { + return !isExcluded(name) && isAccepted(name); + } + + /** + * Checks if name of Cookie match {@link #acceptedPattern} + * + * @param name of Cookie + * @return true|false + */ + protected boolean isAccepted(String name) { + boolean matches = acceptedPattern.matcher(name).matches(); + if (matches) { + if (LOG.isTraceEnabled()) { + LOG.trace("Cookie [#0] matches acceptedPattern [#1]", name, ACCEPTED_PATTERN); + } + } else { + if (LOG.isTraceEnabled()) { + LOG.trace("Cookie [#0] doesn't match acceptedPattern [#1]", name, ACCEPTED_PATTERN); + } + } + return matches; + } + + /** + * Checks if name of Cookie match {@link #excludedPattern} + * + * @param name of Cookie + * @return true|false + */ + protected boolean isExcluded(String name) { + boolean matches = excludedPattern.matcher(name).matches(); + if (matches) { + if (LOG.isTraceEnabled()) { + LOG.trace("Cookie [#0] matches excludedPattern [#1]", name, ExcludedPatterns.CLASS_ACCESS_PATTERN); + } + } else { + if (LOG.isTraceEnabled()) { + LOG.trace("Cookie [#0] doesn't match excludedPattern [#1]", name, ExcludedPatterns.CLASS_ACCESS_PATTERN); + } + } + return matches; + } + /** * Hook that populate cookie value into value stack (hence the action) * if the criteria is satisfied (if the cookie value matches with those configured). diff --git a/core/src/main/resources/struts-default.xml b/core/src/main/resources/struts-default.xml index 87f1ff51a6..6e858017d8 100644 --- a/core/src/main/resources/struts-default.xml +++ b/core/src/main/resources/struts-default.xml @@ -203,7 +203,7 @@ - (.*\.|^)class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.* + ^action:.*,^method:.* @@ -260,7 +260,7 @@ - (.*\.|^)class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.* + ^action:.*,^method:.* @@ -270,7 +270,7 @@ - (.*\.|^)class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.* + ^action:.*,^method:.* @@ -308,7 +308,7 @@ - (.*\.|^)class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.* + ^action:.*,^method:.* diff --git a/core/src/test/java/org/apache/struts2/interceptor/CookieInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/CookieInterceptorTest.java index 2d22facf65..d1014a8de8 100644 --- a/core/src/test/java/org/apache/struts2/interceptor/CookieInterceptorTest.java +++ b/core/src/test/java/org/apache/struts2/interceptor/CookieInterceptorTest.java @@ -22,10 +22,12 @@ package org.apache.struts2.interceptor; import java.util.Collections; +import java.util.HashMap; import java.util.Map; import javax.servlet.http.Cookie; +import com.opensymphony.xwork2.mock.MockActionInvocation; import org.easymock.MockControl; import org.springframework.mock.web.MockHttpServletRequest; @@ -316,6 +318,70 @@ public void testInterceptSelectedCookiesNameAndValue() throws Exception { assertEquals(ActionContext.getContext().getValueStack().findValue("cookie3"), null); } + public void testCookiesWithClassPollution() throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest(); + String pollution1 = "model['class']['classLoader']['jarPath']"; + String pollution2 = "model.class.classLoader.jarPath"; + String pollution3 = "class.classLoader.jarPath"; + String pollution4 = "class['classLoader']['jarPath']"; + String pollution5 = "model[\"class\"]['classLoader']['jarPath']"; + String pollution6 = "class[\"classLoader\"]['jarPath']"; + + request.setCookies( + new Cookie(pollution1, "pollution1"), + new Cookie("pollution1", pollution1), + new Cookie(pollution2, "pollution2"), + new Cookie("pollution2", pollution2), + new Cookie(pollution3, "pollution3"), + new Cookie("pollution3", pollution3), + new Cookie(pollution4, "pollution4"), + new Cookie("pollution4", pollution4), + new Cookie(pollution5, "pollution5"), + new Cookie("pollution5", pollution5), + new Cookie(pollution6, "pollution6"), + new Cookie("pollution6", pollution6) + ); + ServletActionContext.setRequest(request); + + final Map excludedName = new HashMap(); + final Map excludedValue = new HashMap(); + + CookieInterceptor interceptor = new CookieInterceptor() { + @Override + protected boolean isAcceptableName(String name) { + boolean accepted = super.isAcceptableName(name); + excludedName.put(name, accepted); + return accepted; + } + + @Override + protected boolean isAcceptableValue(String value) { + boolean accepted = super.isAcceptableValue(value); + excludedValue.put(value, accepted); + return accepted; + } + }; + interceptor.setCookiesName("*"); + + MockActionInvocation invocation = new MockActionInvocation(); + invocation.setAction(new MockActionWithCookieAware()); + + interceptor.intercept(invocation); + + assertFalse(excludedName.get(pollution1)); + assertFalse(excludedName.get(pollution2)); + assertFalse(excludedName.get(pollution3)); + assertFalse(excludedName.get(pollution4)); + assertFalse(excludedName.get(pollution5)); + assertFalse(excludedName.get(pollution6)); + + assertFalse(excludedValue.get(pollution1)); + assertFalse(excludedValue.get(pollution2)); + assertFalse(excludedValue.get(pollution3)); + assertFalse(excludedValue.get(pollution4)); + assertFalse(excludedValue.get(pollution5)); + assertFalse(excludedValue.get(pollution6)); + } public static class MockActionWithCookieAware extends ActionSupport implements CookiesAware { diff --git a/plugins/cdi/pom.xml b/plugins/cdi/pom.xml index 9c7c503582..8cd0325f94 100644 --- a/plugins/cdi/pom.xml +++ b/plugins/cdi/pom.xml @@ -25,7 +25,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-cdi-plugin diff --git a/plugins/codebehind/pom.xml b/plugins/codebehind/pom.xml index 9cfbbd6e7a..e978b792a2 100644 --- a/plugins/codebehind/pom.xml +++ b/plugins/codebehind/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-codebehind-plugin diff --git a/plugins/config-browser/pom.xml b/plugins/config-browser/pom.xml index f0d9ce231e..284f1c707a 100644 --- a/plugins/config-browser/pom.xml +++ b/plugins/config-browser/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-config-browser-plugin diff --git a/plugins/convention/pom.xml b/plugins/convention/pom.xml index 7b19112e3c..a55a797792 100644 --- a/plugins/convention/pom.xml +++ b/plugins/convention/pom.xml @@ -3,7 +3,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-convention-plugin diff --git a/plugins/dojo/pom.xml b/plugins/dojo/pom.xml index 39d16388b5..29846eafc2 100644 --- a/plugins/dojo/pom.xml +++ b/plugins/dojo/pom.xml @@ -25,7 +25,7 @@ struts2-plugins org.apache.struts - 2.3.18-SNAPSHOT + 2.3.16.2 4.0.0 diff --git a/plugins/dwr/pom.xml b/plugins/dwr/pom.xml index 01ae73464c..dba899b0ae 100644 --- a/plugins/dwr/pom.xml +++ b/plugins/dwr/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-dwr-plugin diff --git a/plugins/embeddedjsp/pom.xml b/plugins/embeddedjsp/pom.xml index 0445f79551..51488bef5c 100644 --- a/plugins/embeddedjsp/pom.xml +++ b/plugins/embeddedjsp/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-embeddedjsp-plugin diff --git a/plugins/gxp/pom.xml b/plugins/gxp/pom.xml index d46ba4c47d..5ef6f6b3e9 100644 --- a/plugins/gxp/pom.xml +++ b/plugins/gxp/pom.xml @@ -3,7 +3,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-gxp-plugin diff --git a/plugins/jasperreports/pom.xml b/plugins/jasperreports/pom.xml index 218ade5114..3cf1c9434e 100644 --- a/plugins/jasperreports/pom.xml +++ b/plugins/jasperreports/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-jasperreports-plugin diff --git a/plugins/javatemplates/pom.xml b/plugins/javatemplates/pom.xml index fbe877665d..e3a44c4fd3 100644 --- a/plugins/javatemplates/pom.xml +++ b/plugins/javatemplates/pom.xml @@ -25,7 +25,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-javatemplates-plugin diff --git a/plugins/jfreechart/pom.xml b/plugins/jfreechart/pom.xml index d591c2d21c..849c815feb 100644 --- a/plugins/jfreechart/pom.xml +++ b/plugins/jfreechart/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-jfreechart-plugin diff --git a/plugins/jsf/pom.xml b/plugins/jsf/pom.xml index 756635e873..33d00ea094 100644 --- a/plugins/jsf/pom.xml +++ b/plugins/jsf/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-jsf-plugin diff --git a/plugins/json/pom.xml b/plugins/json/pom.xml index 7e99c656f0..444d311bb2 100644 --- a/plugins/json/pom.xml +++ b/plugins/json/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-json-plugin diff --git a/plugins/junit/pom.xml b/plugins/junit/pom.xml index aaabc72eb1..2571fcb2c1 100644 --- a/plugins/junit/pom.xml +++ b/plugins/junit/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-junit-plugin diff --git a/plugins/osgi/pom.xml b/plugins/osgi/pom.xml index 9c765dd6d1..11e2c22d37 100644 --- a/plugins/osgi/pom.xml +++ b/plugins/osgi/pom.xml @@ -4,7 +4,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-osgi-plugin diff --git a/plugins/oval/pom.xml b/plugins/oval/pom.xml index b988bde80c..457383fa9d 100644 --- a/plugins/oval/pom.xml +++ b/plugins/oval/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-oval-plugin diff --git a/plugins/pell-multipart/pom.xml b/plugins/pell-multipart/pom.xml index c372a4b997..b2ab339f1f 100644 --- a/plugins/pell-multipart/pom.xml +++ b/plugins/pell-multipart/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-pell-multipart-plugin diff --git a/plugins/plexus/pom.xml b/plugins/plexus/pom.xml index d75733423f..8569137e7f 100644 --- a/plugins/plexus/pom.xml +++ b/plugins/plexus/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-plexus-plugin diff --git a/plugins/pom.xml b/plugins/pom.xml index c2fda24e6f..d98fc9a190 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-parent - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-plugins diff --git a/plugins/portlet-tiles/pom.xml b/plugins/portlet-tiles/pom.xml index 0ce09ff79f..9d41d84fdf 100644 --- a/plugins/portlet-tiles/pom.xml +++ b/plugins/portlet-tiles/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-portlet-tiles-plugin diff --git a/plugins/portlet/pom.xml b/plugins/portlet/pom.xml index 7e7919d14f..8134dad7d5 100644 --- a/plugins/portlet/pom.xml +++ b/plugins/portlet/pom.xml @@ -3,7 +3,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-portlet-plugin diff --git a/plugins/rest/pom.xml b/plugins/rest/pom.xml index 66d566f509..aec40754d7 100644 --- a/plugins/rest/pom.xml +++ b/plugins/rest/pom.xml @@ -26,11 +26,11 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-rest-plugin - 2.3.18-SNAPSHOT + 2.3.16.2 Struts 2 REST Plugin diff --git a/plugins/sitegraph/pom.xml b/plugins/sitegraph/pom.xml index c1e6c1b624..243b1d261f 100644 --- a/plugins/sitegraph/pom.xml +++ b/plugins/sitegraph/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-sitegraph-plugin diff --git a/plugins/sitemesh/pom.xml b/plugins/sitemesh/pom.xml index 6d2039013d..3c7b1b8319 100644 --- a/plugins/sitemesh/pom.xml +++ b/plugins/sitemesh/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-sitemesh-plugin diff --git a/plugins/spring/pom.xml b/plugins/spring/pom.xml index cb0d6a10c6..6bcf25262c 100644 --- a/plugins/spring/pom.xml +++ b/plugins/spring/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-spring-plugin diff --git a/plugins/struts1/pom.xml b/plugins/struts1/pom.xml index 4ae4a237df..fb847998c8 100644 --- a/plugins/struts1/pom.xml +++ b/plugins/struts1/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-struts1-plugin diff --git a/plugins/testng/pom.xml b/plugins/testng/pom.xml index b813949818..eec0caf713 100644 --- a/plugins/testng/pom.xml +++ b/plugins/testng/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-testng-plugin diff --git a/plugins/tiles/pom.xml b/plugins/tiles/pom.xml index a7a188d215..47b3980e81 100644 --- a/plugins/tiles/pom.xml +++ b/plugins/tiles/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-tiles-plugin diff --git a/plugins/tiles3/pom.xml b/plugins/tiles3/pom.xml index ddb92d0f0a..77fb083f6e 100644 --- a/plugins/tiles3/pom.xml +++ b/plugins/tiles3/pom.xml @@ -26,7 +26,7 @@ org.apache.struts struts2-plugins - 2.3.18-SNAPSHOT + 2.3.16.2 struts2-tiles3-plugin diff --git a/pom.xml b/pom.xml index 231a4ed113..9db8cdbebe 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 struts2-parent - 2.3.18-SNAPSHOT + 2.3.16.2 pom Struts 2 http://struts.apache.org/ @@ -31,8 +31,7 @@ scm:git:git://git.apache.org/struts.git scm:git:https://git-wip-us.apache.org/repos/asf/struts.git http://git.apache.org/struts.git - HEAD - + JIRA diff --git a/src/site/resources/archetype-catalog.xml b/src/site/resources/archetype-catalog.xml index d1989bba41..fab8fde9a3 100644 --- a/src/site/resources/archetype-catalog.xml +++ b/src/site/resources/archetype-catalog.xml @@ -7,42 +7,42 @@ org.apache.struts struts2-archetype-blank - 2.3.16.1 + 2.3.16.2 http://repo1.maven.org/maven2/ Struts 2 Archetypes - Blank org.apache.struts struts2-archetype-convention - 2.3.16.1 + 2.3.16.2 http://repo1.maven.org/maven2/ Struts 2 Archetypes - Blank Convention org.apache.struts struts2-archetype-dbportlet - 2.3.16.1 + 2.3.16.2 http://repo1.maven.org/maven2/ Struts 2 Archetypes - Database Portlet org.apache.struts struts2-archetype-plugin - 2.3.16.1 + 2.3.16.2 http://repo1.maven.org/maven2/ Struts 2 Archetypes - Plugin org.apache.struts struts2-archetype-portlet - 2.3.16.1 + 2.3.16.2 http://repo1.maven.org/maven2/ Struts 2 Archetypes - Portlet org.apache.struts struts2-archetype-starter - 2.3.16.1 + 2.3.16.2 http://repo1.maven.org/maven2/ Struts 2 Archetypes - Starter diff --git a/xwork-core/pom.xml b/xwork-core/pom.xml index a35ead49e6..34fe8e2d9a 100644 --- a/xwork-core/pom.xml +++ b/xwork-core/pom.xml @@ -5,7 +5,7 @@ org.apache.struts struts2-parent - 2.3.18-SNAPSHOT + 2.3.16.2 org.apache.struts.xwork diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/ExcludedPatterns.java b/xwork-core/src/main/java/com/opensymphony/xwork2/ExcludedPatterns.java new file mode 100644 index 0000000000..b618a52a04 --- /dev/null +++ b/xwork-core/src/main/java/com/opensymphony/xwork2/ExcludedPatterns.java @@ -0,0 +1,22 @@ +package com.opensymphony.xwork2; + +/** + * ExcludedPatterns contains hard-coded patterns that must be rejected by {@link com.opensymphony.xwork2.interceptor.ParametersInterceptor} + * and partially in CookInterceptor + */ +public class ExcludedPatterns { + + public static final String CLASS_ACCESS_PATTERN = "(.*\\.|^|.*|\\[('|\"))class(\\.|('|\")]|\\[).*"; + + public static final String[] EXCLUDED_PATTERNS = { + CLASS_ACCESS_PATTERN, + "^dojo\\..*", + "^struts\\..*", + "^session\\..*", + "^request\\..*", + "^application\\..*", + "^servlet(Request|Response)\\..*", + "^parameters\\..*" + }; + +} diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java index cb38d573d9..c73b05701d 100644 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java +++ b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java @@ -17,6 +17,7 @@ import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.ExcludedPatterns; import com.opensymphony.xwork2.ValidationAware; import com.opensymphony.xwork2.XWorkConstants; import com.opensymphony.xwork2.conversion.impl.InstantiatingNullHandler; @@ -148,16 +149,20 @@ public class ParametersInterceptor extends MethodFilterInterceptor { private int paramNameMaxLength = PARAM_NAME_MAX_LENGTH; protected boolean ordered = false; - protected Set excludeParams = Collections.emptySet(); + protected Set excludeParams; protected Set acceptParams = Collections.emptySet(); private boolean devMode = false; // Allowed names of parameters - private Pattern acceptedPattern = Pattern.compile(ACCEPTED_PARAM_NAMES); + private Pattern acceptedPattern = Pattern.compile(ACCEPTED_PARAM_NAMES, Pattern.CASE_INSENSITIVE); private ValueStackFactory valueStackFactory; + public ParametersInterceptor() { + initializeHardCodedExcludePatterns(); + } + @Inject public void setValueStackFactory(ValueStackFactory valueStackFactory) { this.valueStackFactory = valueStackFactory; @@ -486,6 +491,13 @@ protected Set getExcludeParamsSet() { return excludeParams; } + protected void initializeHardCodedExcludePatterns() { + excludeParams = new HashSet(); + for (String pattern : ExcludedPatterns.EXCLUDED_PATTERNS) { + excludeParams.add(Pattern.compile(pattern, Pattern.CASE_INSENSITIVE)); + } + } + /** * Sets a comma-delimited list of regular expressions to match * parameters that should be removed from the parameter map. @@ -495,9 +507,8 @@ protected Set getExcludeParamsSet() { public void setExcludeParams(String commaDelim) { Collection excludePatterns = ArrayUtils.asCollection(commaDelim); if (excludePatterns != null) { - excludeParams = new HashSet(); for (String pattern : excludePatterns) { - excludeParams.add(Pattern.compile(pattern)); + excludeParams.add(Pattern.compile(pattern, Pattern.CASE_INSENSITIVE)); } } } diff --git a/xwork-core/src/test/java/com/opensymphony/xwork2/interceptor/ParametersInterceptorTest.java b/xwork-core/src/test/java/com/opensymphony/xwork2/interceptor/ParametersInterceptorTest.java index 5a4485d641..44146666d3 100644 --- a/xwork-core/src/test/java/com/opensymphony/xwork2/interceptor/ParametersInterceptorTest.java +++ b/xwork-core/src/test/java/com/opensymphony/xwork2/interceptor/ParametersInterceptorTest.java @@ -18,6 +18,7 @@ import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionProxy; +import com.opensymphony.xwork2.ExcludedPatterns; import com.opensymphony.xwork2.ModelDrivenAction; import com.opensymphony.xwork2.SimpleAction; import com.opensymphony.xwork2.TestBean; @@ -44,10 +45,12 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.regex.Pattern; /** @@ -268,6 +271,62 @@ public void testParametersDoesNotAffectSession() throws Exception { 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 params = new HashMap() { + { + put(pollution1, "bad"); + put(pollution2, "bad"); + put(pollution3, "bad"); + put(pollution4, "bad"); + put(pollution5, "bad"); + put(pollution6, "bad"); + } + }; + + final Map excluded = new HashMap(); + ParametersInterceptor pi = new ParametersInterceptor() { + + @Override + protected void initializeHardCodedExcludePatterns() { + this.excludeParams = new HashSet(); + } + + @Override + protected boolean isExcluded(String paramName) { + boolean result = super.isExcluded(paramName); + excluded.put(paramName, result); + return result; + } + + }; + + pi.setExcludeParams("(.*\\.|^|.*|\\[('|\"))class(\\.|('|\")]|\\[).*"); + 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 params = new HashMap(); @@ -668,6 +727,11 @@ public void testInternalParametersAreIgnored() throws Exception { assertEquals(expected, actual); } + public void testExcludedPatternsGetInitialized() throws Exception { + ParametersInterceptor parametersInterceptor = new ParametersInterceptor(); + assertEquals(ExcludedPatterns.EXCLUDED_PATTERNS.length, parametersInterceptor.excludeParams.size()); + } + private ValueStack injectValueStack(Map actual) { ValueStack stack = createStubValueStack(actual); container.inject(stack);