BAEL-6848: Set a Parameter in a HttpServletRequest in Java
This commit is contained in:
parent
63033cd8cf
commit
8d115be74e
|
@ -22,6 +22,11 @@
|
|||
<artifactId>commons-fileupload</artifactId>
|
||||
<version>${commons-fileupload.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
<version>${commons-text.version}</version>
|
||||
</dependency>
|
||||
<!-- Servlet -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
|
@ -76,6 +81,16 @@
|
|||
</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-maven-plugin</artifactId>
|
||||
<version>${jetty-maven-plugin.version}</version>
|
||||
<configuration>
|
||||
<webApp>
|
||||
<contextPath>/</contextPath>
|
||||
</webApp>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -84,6 +99,8 @@
|
|||
<jmockit.version>1.49</jmockit.version>
|
||||
<spring-test.version>5.3.20</spring-test.version>
|
||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
||||
<jetty-maven-plugin.version>10.0.4</jetty-maven-plugin.version>
|
||||
<commons-text.version>1.10.0</commons-text.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.*;
|
||||
|
||||
@WebServlet(name = "LanguageServlet", urlPatterns = "/setparam/lang")
|
||||
public class LanguageServlet extends HttpServlet {
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
|
||||
SetParameterRequestWrapper requestWrapper = new SetParameterRequestWrapper(request);
|
||||
requestWrapper.setParameter("locale", Locale.getDefault().getLanguage());
|
||||
request.getRequestDispatcher("/setparam/3rd_party_module.jsp").forward(requestWrapper, response);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.annotation.WebFilter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@WebFilter(urlPatterns = { "/setparam/with-sanitize.jsp" })
|
||||
public class SanitizeParametersFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
HttpServletRequest httpReq = (HttpServletRequest) request;
|
||||
chain.doFilter(new SanitizeParametersRequestWrapper(httpReq), response);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
|
||||
public class SanitizeParametersRequestWrapper extends HttpServletRequestWrapper {
|
||||
|
||||
private final Map<String, String[]> sanitizedMap;
|
||||
|
||||
public SanitizeParametersRequestWrapper(HttpServletRequest request) {
|
||||
super(request);
|
||||
sanitizedMap = Collections.unmodifiableMap(
|
||||
request.getParameterMap().entrySet().stream()
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
entry -> Arrays.stream(entry.getValue())
|
||||
.map(StringEscapeUtils::escapeHtml4)
|
||||
.toArray(String[]::new)
|
||||
)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String[]> getParameterMap() {
|
||||
return sanitizedMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterValues(String name) {
|
||||
return Optional.ofNullable(getParameterMap().get(name))
|
||||
.map(values -> Arrays.copyOf(values, values.length))
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameter(String name) {
|
||||
return Optional.ofNullable(getParameterValues(name))
|
||||
.map(values -> values[0])
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
|
||||
public class SetParameterRequestWrapper extends HttpServletRequestWrapper {
|
||||
|
||||
private final Map<String, String[]> paramMap;
|
||||
|
||||
public SetParameterRequestWrapper(HttpServletRequest request) {
|
||||
super(request);
|
||||
paramMap = new HashMap<>(request.getParameterMap());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String[]> getParameterMap() {
|
||||
return Collections.unmodifiableMap(paramMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterValues(String name) {
|
||||
return Optional.ofNullable(getParameterMap().get(name))
|
||||
.map(values -> Arrays.copyOf(values, values.length))
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameter(String name) {
|
||||
return Optional.ofNullable(getParameterValues(name))
|
||||
.map(values -> values[0])
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public void setParameter(String name, String value) {
|
||||
paramMap.put(name, new String[] {value});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<%@ page import="java.util.*"%>
|
||||
<html>
|
||||
<head>
|
||||
<title>3rd party Module</title>
|
||||
</head>
|
||||
<body>
|
||||
<%
|
||||
String localeStr = request.getParameter("locale");
|
||||
Locale currentLocale = (localeStr != null ? new Locale(localeStr) : null);
|
||||
%>
|
||||
The language you have selected: <%=currentLocale != null ? currentLocale.getDisplayLanguage(currentLocale) : " None"%>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Sanitized request parameter</title>
|
||||
</head>
|
||||
<body>
|
||||
The text below comes from request parameter "input":
|
||||
<br/>
|
||||
<%=request.getParameter("input")%>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Non sanitized request parameter</title>
|
||||
</head>
|
||||
<body>
|
||||
The text below comes from request parameter "input":
|
||||
<br/>
|
||||
<%=request.getParameter("input")%>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,34 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
public class LanguageServletIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void whenGetRequestUsingHttpClient_thenResponseBodyContainsDefaultLanguage() throws Exception {
|
||||
|
||||
// When
|
||||
HttpClient client = HttpClientBuilder.create().build();
|
||||
HttpGet method = new HttpGet("http://localhost:8080/setparam/lang");
|
||||
HttpResponse httpResponse = client.execute(method);
|
||||
|
||||
// Then
|
||||
Locale defaultLocale = Locale.getDefault();
|
||||
String expectedLanguage = defaultLocale.getDisplayLanguage(defaultLocale);
|
||||
|
||||
HttpEntity entity = httpResponse.getEntity();
|
||||
String responseBody = EntityUtils.toString(entity, "UTF-8");
|
||||
assertTrue(responseBody.contains("The language you have selected: " + expectedLanguage));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SanitizeParametersRequestIntegrationTest {
|
||||
|
||||
private static String PARAM_INPUT;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() throws UnsupportedEncodingException {
|
||||
PARAM_INPUT = URLEncoder.encode("<script>alert('Hello');</script>", "UTF-8");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenInputParameterContainsXss_thenResponseBodyContainsSanitizedValue() throws Exception {
|
||||
|
||||
// When
|
||||
HttpClient client = HttpClientBuilder.create().build();
|
||||
HttpGet method = new HttpGet(String.format("http://localhost:8080/setparam/with-sanitize.jsp?input=%s", PARAM_INPUT));
|
||||
HttpResponse httpResponse = client.execute(method);
|
||||
|
||||
// Then
|
||||
HttpEntity entity = httpResponse.getEntity();
|
||||
String responseBody = EntityUtils.toString(entity, "UTF-8");
|
||||
assertTrue(responseBody.contains("<script>alert('Hello');</script>"));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class SanitizeParametersRequestWrapperUnitTest {
|
||||
|
||||
private String NEW_VALUE = "NEW VALUE";
|
||||
|
||||
private Map<String, String[]> parameterMap;
|
||||
|
||||
@Mock
|
||||
private HttpServletRequest request;
|
||||
|
||||
@Before
|
||||
public void initBeforeEachTest() {
|
||||
parameterMap = new HashMap<>();
|
||||
parameterMap.put("input", new String[] {"<script>alert('Hello');</script>"});
|
||||
when(request.getParameterMap()).thenReturn(parameterMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetParameterViaWrapper_thenParameterReturnedIsSanitized() {
|
||||
SanitizeParametersRequestWrapper wrapper = new SanitizeParametersRequestWrapper(request);
|
||||
String actualValue = wrapper.getParameter("input");
|
||||
|
||||
assertEquals(actualValue, "<script>alert('Hello');</script>");
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void whenPutValueToWrapperParameterMap_thenThrowsUnsupportedOperationException() {
|
||||
SanitizeParametersRequestWrapper wrapper = new SanitizeParametersRequestWrapper(request);
|
||||
Map<String, String[]> wrapperParamMap = wrapper.getParameterMap();
|
||||
wrapperParamMap.put("input", new String[] {NEW_VALUE});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSetValueToWrapperParametersStringArray_thenThe2ndCallShouldNotEqualToNewValue() {
|
||||
SanitizeParametersRequestWrapper wrapper = new SanitizeParametersRequestWrapper(request);
|
||||
String[] firstCallValues = wrapper.getParameterValues("input");
|
||||
|
||||
firstCallValues[0] = NEW_VALUE;
|
||||
String[] secondCallValues = wrapper.getParameterValues("input");
|
||||
assertNotEquals(firstCallValues, secondCallValues);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class SetParameterRequestWrapperUnitTest {
|
||||
|
||||
private String NEW_VALUE = "NEW VALUE";
|
||||
|
||||
private Map<String, String[]> parameterMap;
|
||||
|
||||
@Mock
|
||||
private HttpServletRequest request;
|
||||
|
||||
@Before
|
||||
public void initBeforeEachTest() {
|
||||
parameterMap = new HashMap<>();
|
||||
parameterMap.put("input", new String[] {"inputValue"});
|
||||
when(request.getParameterMap()).thenReturn(parameterMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSetParameterViaWrapper_thenGetParameterShouldReturnTheSameValue() {
|
||||
SetParameterRequestWrapper wrapper = new SetParameterRequestWrapper(request);
|
||||
wrapper.setParameter("newInput", "newInputValue");
|
||||
String actualValue = wrapper.getParameter("newInput");
|
||||
|
||||
assertEquals(actualValue, "newInputValue");
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void whenPutValueToWrapperParameterMap_thenThrowsUnsupportedOperationException() {
|
||||
SetParameterRequestWrapper wrapper = new SetParameterRequestWrapper(request);
|
||||
Map<String, String[]> wrapperParamMap = wrapper.getParameterMap();
|
||||
wrapperParamMap.put("input", new String[] {NEW_VALUE});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSetValueToWrapperParametersStringArray_thenThe2ndCallShouldNotEqualToNewValue() {
|
||||
SetParameterRequestWrapper wrapper = new SetParameterRequestWrapper(request);
|
||||
String[] firstCallValues = wrapper.getParameterValues("input");
|
||||
|
||||
firstCallValues[0] = NEW_VALUE;
|
||||
String[] secondCallValues = wrapper.getParameterValues("input");
|
||||
assertNotEquals(firstCallValues, secondCallValues);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class UnsanitizedParametersRequestIntegrationTest {
|
||||
|
||||
private static final String TAG_SCRIPT = "<script>alert('Hello');</script>";
|
||||
|
||||
private static String PARAM_INPUT;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() throws UnsupportedEncodingException {
|
||||
PARAM_INPUT = URLEncoder.encode(TAG_SCRIPT, "UTF-8");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenInputParameterContainsXss_thenResponseBodyContainsUnsanitizedValue() throws Exception {
|
||||
|
||||
// When
|
||||
HttpClient client = HttpClientBuilder.create().build();
|
||||
HttpGet method = new HttpGet(String.format("http://localhost:8080/setparam/without-sanitize.jsp?input=%s", PARAM_INPUT));
|
||||
HttpResponse httpResponse = client.execute(method);
|
||||
|
||||
// Then
|
||||
HttpEntity entity = httpResponse.getEntity();
|
||||
String responseBody = EntityUtils.toString(entity, "UTF-8");
|
||||
assertTrue(responseBody.contains(TAG_SCRIPT));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue