CookieInterceptorTest.java
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.struts2.interceptor;
import org.apache.struts2.action.Action;
import org.apache.struts2.ActionContext;
import org.apache.struts2.ActionInvocation;
import org.apache.struts2.ActionSupport;
import org.apache.struts2.mock.MockActionInvocation;
import org.apache.struts2.security.DefaultAcceptedPatternsChecker;
import org.apache.struts2.security.DefaultExcludedPatternsChecker;
import jakarta.servlet.http.Cookie;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsInternalTestCase;
import org.apache.struts2.action.CookiesAware;
import org.apache.struts2.interceptor.parameter.StrutsParameter;
import org.springframework.mock.web.MockHttpServletRequest;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
public class CookieInterceptorTest extends StrutsInternalTestCase {
public void testIntercepDefault() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
);
ServletActionContext.setRequest(request);
MockActionWithCookieAware action = new MockActionWithCookieAware();
ActionContext.getContext().getValueStack().push(action);
ActionInvocation invocation = (ActionInvocation) createMock(ActionInvocation.class);
expect(invocation.getAction()).andReturn(action);
expect(invocation.invoke()).andReturn(Action.SUCCESS);
replay(invocation);
// by default the interceptor doesn't accept any cookies
CookieInterceptor interceptor = new CookieInterceptor();
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.intercept(invocation);
assertTrue(action.getCookiesMap().isEmpty());
assertNull(action.getCookie1(), null);
assertNull(action.getCookie2(), null);
assertNull(action.getCookie3(), null);
assertNull(ActionContext.getContext().getValueStack().findValue("cookie1"));
assertNull(ActionContext.getContext().getValueStack().findValue("cookie2"));
assertNull(ActionContext.getContext().getValueStack().findValue("cookie3"));
verify(invocation);
}
public void testInterceptAll1() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
);
ServletActionContext.setRequest(request);
MockActionWithCookieAware action = new MockActionWithCookieAware();
ActionContext.getContext().getValueStack().push(action);
ActionInvocation invocation = (ActionInvocation) createMock(ActionInvocation.class);
expect(invocation.getAction()).andReturn(action);
expect(invocation.invoke()).andReturn(Action.SUCCESS);
replay(invocation);
CookieInterceptor interceptor = new CookieInterceptor();
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.setCookiesName("*");
interceptor.setCookiesValue("*");
interceptor.intercept(invocation);
assertFalse(action.getCookiesMap().isEmpty());
assertEquals(action.getCookiesMap().size(), 3);
assertEquals(action.getCookiesMap().get("cookie1"), "cookie1value");
assertEquals(action.getCookiesMap().get("cookie2"), "cookie2value");
assertEquals(action.getCookiesMap().get("cookie3"), "cookie3value");
assertEquals(action.getCookie1(), "cookie1value");
assertEquals(action.getCookie2(), "cookie2value");
assertEquals(action.getCookie3(), "cookie3value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie1"), "cookie1value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie2"), "cookie2value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie3"), "cookie3value");
verify(invocation);
}
public void testInterceptAll2() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
);
ServletActionContext.setRequest(request);
MockActionWithCookieAware action = new MockActionWithCookieAware();
ActionContext.getContext().getValueStack().push(action);
ActionInvocation invocation = (ActionInvocation) createMock(ActionInvocation.class);
expect(invocation.getAction()).andReturn(action);
expect(invocation.invoke()).andReturn(Action.SUCCESS);
replay(invocation);
CookieInterceptor interceptor = new CookieInterceptor();
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.setCookiesName("cookie1, cookie2, cookie3");
interceptor.setCookiesValue("cookie1value, cookie2value, cookie3value");
interceptor.intercept(invocation);
assertFalse(action.getCookiesMap().isEmpty());
assertEquals(action.getCookiesMap().size(), 3);
assertEquals(action.getCookiesMap().get("cookie1"), "cookie1value");
assertEquals(action.getCookiesMap().get("cookie2"), "cookie2value");
assertEquals(action.getCookiesMap().get("cookie3"), "cookie3value");
assertEquals(action.getCookie1(), "cookie1value");
assertEquals(action.getCookie2(), "cookie2value");
assertEquals(action.getCookie3(), "cookie3value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie1"), "cookie1value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie2"), "cookie2value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie3"), "cookie3value");
verify(invocation);
}
public void testInterceptSelectedCookiesNameOnly1() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
);
ServletActionContext.setRequest(request);
MockActionWithCookieAware action = new MockActionWithCookieAware();
ActionContext.getContext().getValueStack().push(action);
ActionInvocation invocation = (ActionInvocation) createMock(ActionInvocation.class);
expect(invocation.getAction()).andReturn(action);
expect(invocation.invoke()).andReturn(Action.SUCCESS);
replay(invocation);
CookieInterceptor interceptor = new CookieInterceptor();
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.setCookiesName("cookie1, cookie3");
interceptor.setCookiesValue("cookie1value, cookie2value, cookie3value");
interceptor.intercept(invocation);
assertFalse(action.getCookiesMap().isEmpty());
assertEquals(action.getCookiesMap().size(), 2);
assertEquals(action.getCookiesMap().get("cookie1"), "cookie1value");
assertEquals(action.getCookiesMap().get("cookie2"), null);
assertEquals(action.getCookiesMap().get("cookie3"), "cookie3value");
assertEquals(action.getCookie1(), "cookie1value");
assertEquals(action.getCookie2(), null);
assertEquals(action.getCookie3(), "cookie3value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie1"), "cookie1value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie2"), null);
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie3"), "cookie3value");
verify(invocation);
}
public void testInterceptSelectedCookiesNameOnly2() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
);
ServletActionContext.setRequest(request);
MockActionWithCookieAware action = new MockActionWithCookieAware();
ActionContext.getContext().getValueStack().push(action);
ActionInvocation invocation = (ActionInvocation) createMock(ActionInvocation.class);
expect(invocation.getAction()).andReturn(action);
expect(invocation.invoke()).andReturn(Action.SUCCESS);
replay(invocation);
CookieInterceptor interceptor = new CookieInterceptor();
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.setCookiesName("cookie1, cookie3");
interceptor.setCookiesValue("*");
interceptor.intercept(invocation);
assertFalse(action.getCookiesMap().isEmpty());
assertEquals(action.getCookiesMap().size(), 2);
assertEquals(action.getCookiesMap().get("cookie1"), "cookie1value");
assertEquals(action.getCookiesMap().get("cookie2"), null);
assertEquals(action.getCookiesMap().get("cookie3"), "cookie3value");
assertEquals(action.getCookie1(), "cookie1value");
assertEquals(action.getCookie2(), null);
assertEquals(action.getCookie3(), "cookie3value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie1"), "cookie1value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie2"), null);
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie3"), "cookie3value");
verify(invocation);
}
public void testInterceptSelectedCookiesNameOnly3() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
);
ServletActionContext.setRequest(request);
MockActionWithCookieAware action = new MockActionWithCookieAware();
ActionContext.getContext().getValueStack().push(action);
ActionInvocation invocation = (ActionInvocation) createMock(ActionInvocation.class);
expect(invocation.getAction()).andReturn(action);
expect(invocation.invoke()).andReturn(Action.SUCCESS);
replay(invocation);
CookieInterceptor interceptor = new CookieInterceptor();
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.setCookiesName("cookie1, cookie3");
interceptor.setCookiesValue("");
interceptor.intercept(invocation);
assertFalse(action.getCookiesMap().isEmpty());
assertEquals(action.getCookiesMap().size(), 2);
assertEquals(action.getCookiesMap().get("cookie1"), "cookie1value");
assertEquals(action.getCookiesMap().get("cookie2"), null);
assertEquals(action.getCookiesMap().get("cookie3"), "cookie3value");
assertEquals(action.getCookie1(), "cookie1value");
assertEquals(action.getCookie2(), null);
assertEquals(action.getCookie3(), "cookie3value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie1"), "cookie1value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie2"), null);
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie3"), "cookie3value");
verify(invocation);
}
public void testInterceptSelectedCookiesNameAndValue() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
);
ServletActionContext.setRequest(request);
MockActionWithCookieAware action = new MockActionWithCookieAware();
ActionContext.getContext().getValueStack().push(action);
ActionInvocation invocation = (ActionInvocation) createMock(ActionInvocation.class);
expect(invocation.getAction()).andReturn(action);
expect(invocation.invoke()).andReturn(Action.SUCCESS);
replay(invocation);
CookieInterceptor interceptor = new CookieInterceptor();
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.setCookiesName("cookie1, cookie3");
interceptor.setCookiesValue("cookie1value");
interceptor.intercept(invocation);
assertFalse(action.getCookiesMap().isEmpty());
assertEquals(action.getCookiesMap().size(), 1);
assertEquals(action.getCookiesMap().get("cookie1"), "cookie1value");
assertEquals(action.getCookiesMap().get("cookie2"), null);
assertEquals(action.getCookiesMap().get("cookie3"), null);
assertEquals(action.getCookie1(), "cookie1value");
assertEquals(action.getCookie2(), null);
assertEquals(action.getCookie3(), null);
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie1"), "cookie1value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie2"), null);
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie3"), null);
verify(invocation);
}
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']";
try {
new Cookie(pollution1, "pollution1");
fail("It shouldn't be possible to create cookie: " + pollution1);
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage(), e.getMessage().startsWith("Cookie name \"" + pollution1 + "\" is a reserved token"));
}
try {
new Cookie(pollution4, "pollution4");
fail("It shouldn't be possible to create cookie: " + pollution4);
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage(), e.getMessage().startsWith("Cookie name \"" + pollution4 + "\" is a reserved token"));
}
try {
new Cookie(pollution5, "pollution5");
fail("It shouldn't be possible to create cookie: " + pollution5);
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage(), e.getMessage().startsWith("Cookie name \"" + pollution5 + "\" is a reserved token"));
}
try {
new Cookie(pollution6, "pollution6");
fail("It shouldn't be possible to create cookie: " + pollution6);
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage(), e.getMessage().startsWith("Cookie name \"" + pollution6 + "\" is a reserved token"));
}
request.setCookies(
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("pollution5", pollution5),
new Cookie("pollution6", pollution6)
);
ServletActionContext.setRequest(request);
final Map<String, Boolean> excludedName = new HashMap<String, Boolean>();
CookieInterceptor interceptor = new CookieInterceptor() {
@Override
protected boolean isAcceptableName(String name) {
boolean accepted = super.isAcceptableName(name);
excludedName.put(name, accepted);
return accepted;
}
};
DefaultExcludedPatternsChecker excludedPatternsChecker = new DefaultExcludedPatternsChecker();
excludedPatternsChecker.setAdditionalExcludePatterns(".*(^|\\.|\\[|'|\")class(\\.|\\[|'|\").*");
interceptor.setExcludedPatternsChecker(excludedPatternsChecker);
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
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));
}
public void testCookiesWithStrutsInternalsAccess() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
String sessionCookieName = "session.userId";
String sessionCookieValue = "session.userId=1";
String appCookieName = "application.userId";
String appCookieValue = "application.userId=1";
String reqCookieName = "request.userId";
String reqCookieValue = "request.userId=1";
request.setCookies(
new Cookie(sessionCookieName, "1"),
new Cookie("1", sessionCookieValue),
new Cookie(appCookieName, "1"),
new Cookie("1", appCookieValue),
new Cookie(reqCookieName, "1"),
new Cookie("1", reqCookieValue)
);
ServletActionContext.setRequest(request);
final Map<String, Boolean> excludedName = new HashMap<String, Boolean>();
CookieInterceptor interceptor = new CookieInterceptor() {
@Override
protected boolean isAcceptableName(String name) {
boolean accepted = super.isAcceptableName(name);
excludedName.put(name, accepted);
return accepted;
}
};
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.setCookiesName("*");
MockActionInvocation invocation = new MockActionInvocation();
invocation.setAction(new MockActionWithCookieAware());
interceptor.intercept(invocation);
assertFalse(excludedName.get(sessionCookieName));
assertFalse(excludedName.get(appCookieName));
assertFalse(excludedName.get(reqCookieName));
}
public static class MockActionWithCookieAware extends ActionSupport implements CookiesAware {
private static final long serialVersionUID = -6202290616812813386L;
private Map cookies = Collections.EMPTY_MAP;
private String cookie1;
private String cookie2;
private String cookie3;
@Override
public void withCookies(Map<String, String> cookies) {
this.cookies = cookies;
}
public Map getCookiesMap() {
return this.cookies;
}
public String getCookie1() {
return cookie1;
}
@StrutsParameter
public void setCookie1(String cookie1) {
this.cookie1 = cookie1;
}
public String getCookie2() {
return cookie2;
}
@StrutsParameter
public void setCookie2(String cookie2) {
this.cookie2 = cookie2;
}
public String getCookie3() {
return cookie3;
}
@StrutsParameter
public void setCookie3(String cookie3) {
this.cookie3 = cookie3;
}
}
}