7 changed files with 610 additions and 12 deletions
@ -0,0 +1,239 @@
@@ -0,0 +1,239 @@
|
||||
/* |
||||
* Copyright 2012-2017 the original author or authors. |
||||
* |
||||
* 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 org.springframework.security.web.firewall; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.util.Arrays; |
||||
import java.util.Collection; |
||||
import java.util.Collections; |
||||
import java.util.HashSet; |
||||
import java.util.List; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* A strict implementation of {@link HttpFirewall} that rejects any suspicious requests |
||||
* with a {@link RequestRejectedException}. |
||||
* |
||||
* @author Rob Winch |
||||
* @since 5.0.1 |
||||
*/ |
||||
public class StrictHttpFirewall implements HttpFirewall { |
||||
private static final String ENCODED_PERCENT = "%25"; |
||||
|
||||
private static final String PERCENT = "%"; |
||||
|
||||
private static final List<String> FORBIDDEN_ENCODED_PERIOD = Collections.unmodifiableList(Arrays.asList("%2e", "%2E")); |
||||
|
||||
private static final List<String> FORBIDDEN_SEMICOLON = Collections.unmodifiableList(Arrays.asList(";", "%3b", "%3B")); |
||||
|
||||
private static final List<String> FORBIDDEN_FORWARDSLASH = Collections.unmodifiableList(Arrays.asList("%2f", "%2F")); |
||||
|
||||
private static final List<String> FORBIDDEN_BACKSLASH = Collections.unmodifiableList(Arrays.asList("\\", "%5c", "%5C")); |
||||
|
||||
private Set<String> encodedUrlBlacklist = new HashSet<String>(); |
||||
|
||||
private Set<String> decodedUrlBlacklist = new HashSet<String>(); |
||||
|
||||
public StrictHttpFirewall() { |
||||
urlBlacklistsAddAll(FORBIDDEN_SEMICOLON); |
||||
urlBlacklistsAddAll(FORBIDDEN_FORWARDSLASH); |
||||
urlBlacklistsAddAll(FORBIDDEN_BACKSLASH); |
||||
|
||||
this.encodedUrlBlacklist.add(ENCODED_PERCENT); |
||||
this.encodedUrlBlacklist.addAll(FORBIDDEN_ENCODED_PERIOD); |
||||
this.decodedUrlBlacklist.add(PERCENT); |
||||
} |
||||
|
||||
/** |
||||
* |
||||
* @param allowSemicolon |
||||
*/ |
||||
public void setAllowSemicolon(boolean allowSemicolon) { |
||||
if (allowSemicolon) { |
||||
urlBlacklistsRemoveAll(FORBIDDEN_SEMICOLON); |
||||
} else { |
||||
urlBlacklistsAddAll(FORBIDDEN_SEMICOLON); |
||||
} |
||||
} |
||||
|
||||
public void setAllowUrlEncodedSlash(boolean allowUrlEncodedSlash) { |
||||
if (allowUrlEncodedSlash) { |
||||
urlBlacklistsRemoveAll(FORBIDDEN_FORWARDSLASH); |
||||
} else { |
||||
urlBlacklistsAddAll(FORBIDDEN_FORWARDSLASH); |
||||
} |
||||
} |
||||
|
||||
public void setAllowUrlEncodedPeriod(boolean allowUrlEncodedPeriod) { |
||||
if (allowUrlEncodedPeriod) { |
||||
this.encodedUrlBlacklist.removeAll(FORBIDDEN_ENCODED_PERIOD); |
||||
} else { |
||||
this.encodedUrlBlacklist.addAll(FORBIDDEN_ENCODED_PERIOD); |
||||
} |
||||
} |
||||
|
||||
public void setAllowBackSlash(boolean allowBackSlash) { |
||||
if (allowBackSlash) { |
||||
urlBlacklistsRemoveAll(FORBIDDEN_BACKSLASH); |
||||
} else { |
||||
urlBlacklistsAddAll(FORBIDDEN_BACKSLASH); |
||||
} |
||||
} |
||||
|
||||
public void setAllowUrlEncodedPercent(boolean allowUrlEncodedPercent) { |
||||
if (allowUrlEncodedPercent) { |
||||
this.encodedUrlBlacklist.remove(ENCODED_PERCENT); |
||||
this.decodedUrlBlacklist.remove(PERCENT); |
||||
} else { |
||||
this.encodedUrlBlacklist.add(ENCODED_PERCENT); |
||||
this.decodedUrlBlacklist.add(PERCENT); |
||||
} |
||||
} |
||||
|
||||
private void urlBlacklistsAddAll(Collection<String> values) { |
||||
this.encodedUrlBlacklist.addAll(values); |
||||
this.decodedUrlBlacklist.addAll(values); |
||||
} |
||||
|
||||
private void urlBlacklistsRemoveAll(Collection<String> values) { |
||||
this.encodedUrlBlacklist.removeAll(values); |
||||
this.decodedUrlBlacklist.removeAll(values); |
||||
} |
||||
|
||||
@Override |
||||
public FirewalledRequest getFirewalledRequest(HttpServletRequest request) throws RequestRejectedException { |
||||
rejectedBlacklistedUrls(request); |
||||
|
||||
if (!isNormalized(request)) { |
||||
throw new RequestRejectedException("The request was rejected because the URL was not normalized."); |
||||
} |
||||
|
||||
String requestUri = request.getRequestURI(); |
||||
if (!containsOnlyPrintableAsciiCharacters(requestUri)) { |
||||
throw new RequestRejectedException("The requestURI was rejected because it can only contain printable ASCII characters."); |
||||
} |
||||
return new FirewalledRequest(request) { |
||||
@Override |
||||
public void reset() { |
||||
} |
||||
}; |
||||
} |
||||
|
||||
private void rejectedBlacklistedUrls(HttpServletRequest request) { |
||||
for (String forbidden : this.encodedUrlBlacklist) { |
||||
if (encodedUrlContains(request, forbidden)) { |
||||
throw new RequestRejectedException("The request was rejected because the URL contained a potentially malicious String \"" + forbidden + "\""); |
||||
} |
||||
} |
||||
for (String forbidden : this.decodedUrlBlacklist) { |
||||
if (decodedUrlContains(request, forbidden)) { |
||||
throw new RequestRejectedException("The request was rejected because the URL contained a potentially malicious String \"" + forbidden + "\""); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public HttpServletResponse getFirewalledResponse(HttpServletResponse response) { |
||||
return new FirewalledResponse(response); |
||||
} |
||||
|
||||
private static boolean isNormalized(HttpServletRequest request) { |
||||
if (!isNormalized(request.getRequestURI())) { |
||||
return false; |
||||
} |
||||
if (!isNormalized(request.getContextPath())) { |
||||
return false; |
||||
} |
||||
if (!isNormalized(request.getServletPath())) { |
||||
return false; |
||||
} |
||||
if (!isNormalized(request.getPathInfo())) { |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
private static boolean encodedUrlContains(HttpServletRequest request, String value) { |
||||
if (valueContains(request.getContextPath(), value)) { |
||||
return true; |
||||
} |
||||
return valueContains(request.getRequestURI(), value); |
||||
} |
||||
|
||||
private static boolean decodedUrlContains(HttpServletRequest request, String value) { |
||||
if (valueContains(request.getServletPath(), value)) { |
||||
return true; |
||||
} |
||||
if (valueContains(request.getPathInfo(), value)) { |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private static boolean containsOnlyPrintableAsciiCharacters(String uri) { |
||||
int length = uri.length(); |
||||
for (int i = 0; i < length; i++) { |
||||
char c = uri.charAt(i); |
||||
if (c < '\u0021' || '\u007e' < c) { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
private static boolean valueContains(String value, String contains) { |
||||
return value != null && value.contains(contains); |
||||
} |
||||
|
||||
/** |
||||
* Checks whether a path is normalized (doesn't contain path traversal |
||||
* sequences like "./", "/../" or "/.") |
||||
* |
||||
* @param path |
||||
* the path to test |
||||
* @return true if the path doesn't contain any path-traversal character |
||||
* sequences. |
||||
*/ |
||||
private static boolean isNormalized(String path) { |
||||
if (path == null) { |
||||
return true; |
||||
} |
||||
|
||||
if (path.indexOf("//") > 0) { |
||||
return false; |
||||
} |
||||
|
||||
for (int j = path.length(); j > 0;) { |
||||
int i = path.lastIndexOf('/', j - 1); |
||||
int gap = j - i; |
||||
|
||||
if (gap == 2 && path.charAt(i + 1) == '.') { |
||||
// ".", "/./" or "/."
|
||||
return false; |
||||
} else if (gap == 3 && path.charAt(i + 1) == '.' && path.charAt(i + 2) == '.') { |
||||
return false; |
||||
} |
||||
|
||||
j = i; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,351 @@
@@ -0,0 +1,351 @@
|
||||
/* |
||||
* Copyright 2012-2017 the original author or authors. |
||||
* |
||||
* 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 org.springframework.security.web.firewall; |
||||
|
||||
import org.junit.Test; |
||||
import org.springframework.mock.web.MockHttpServletRequest; |
||||
|
||||
import static org.assertj.core.api.Assertions.fail; |
||||
|
||||
/** |
||||
* @author Rob Winch |
||||
*/ |
||||
public class StrictHttpFirewallTests { |
||||
public String[] unnormalizedPaths = { "/..", "/./path/", "/path/path/.", "/path/path//.", "./path/../path//.", |
||||
"./path", ".//path", ".", "/path//" }; |
||||
|
||||
private StrictHttpFirewall firewall = new StrictHttpFirewall(); |
||||
|
||||
private MockHttpServletRequest request = new MockHttpServletRequest(); |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenRequestURINotNormalizedThenThrowsRequestRejectedException() throws Exception { |
||||
for (String path : this.unnormalizedPaths) { |
||||
this.request = new MockHttpServletRequest(); |
||||
this.request.setRequestURI(path); |
||||
try { |
||||
this.firewall.getFirewalledRequest(this.request); |
||||
fail(path + " is un-normalized"); |
||||
} catch (RequestRejectedException expected) { |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenContextPathNotNormalizedThenThrowsRequestRejectedException() throws Exception { |
||||
for (String path : this.unnormalizedPaths) { |
||||
this.request = new MockHttpServletRequest(); |
||||
this.request.setContextPath(path); |
||||
try { |
||||
this.firewall.getFirewalledRequest(this.request); |
||||
fail(path + " is un-normalized"); |
||||
} catch (RequestRejectedException expected) { |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenServletPathNotNormalizedThenThrowsRequestRejectedException() throws Exception { |
||||
for (String path : this.unnormalizedPaths) { |
||||
this.request = new MockHttpServletRequest(); |
||||
this.request.setServletPath(path); |
||||
try { |
||||
this.firewall.getFirewalledRequest(this.request); |
||||
fail(path + " is un-normalized"); |
||||
} catch (RequestRejectedException expected) { |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenPathInfoNotNormalizedThenThrowsRequestRejectedException() throws Exception { |
||||
for (String path : this.unnormalizedPaths) { |
||||
this.request = new MockHttpServletRequest(); |
||||
this.request.setPathInfo(path); |
||||
try { |
||||
this.firewall.getFirewalledRequest(this.request); |
||||
fail(path + " is un-normalized"); |
||||
} catch (RequestRejectedException expected) { |
||||
} |
||||
} |
||||
} |
||||
|
||||
// --- ; ---
|
||||
|
||||
@Test(expected = RequestRejectedException.class) |
||||
public void getFirewalledRequestWhenSemicolonInContextPathThenThrowsRequestRejectedException() { |
||||
this.request.setContextPath(";/context"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test(expected = RequestRejectedException.class) |
||||
public void getFirewalledRequestWhenSemicolonInServletPathThenThrowsRequestRejectedException() { |
||||
this.request.setServletPath("/spring;/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test(expected = RequestRejectedException.class) |
||||
public void getFirewalledRequestWhenSemicolonInPathInfoThenThrowsRequestRejectedException() { |
||||
this.request.setPathInfo("/path;/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test(expected = RequestRejectedException.class) |
||||
public void getFirewalledRequestWhenSemicolonInRequestUriThenThrowsRequestRejectedException() { |
||||
this.request.setRequestURI("/path;/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test(expected = RequestRejectedException.class) |
||||
public void getFirewalledRequestWhenEncodedSemicolonInContextPathThenThrowsRequestRejectedException() { |
||||
this.request.setContextPath("%3B/context"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test(expected = RequestRejectedException.class) |
||||
public void getFirewalledRequestWhenEncodedSemicolonInServletPathThenThrowsRequestRejectedException() { |
||||
this.request.setServletPath("/spring%3B/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test(expected = RequestRejectedException.class) |
||||
public void getFirewalledRequestWhenEncodedSemicolonInPathInfoThenThrowsRequestRejectedException() { |
||||
this.request.setPathInfo("/path%3B/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test(expected = RequestRejectedException.class) |
||||
public void getFirewalledRequestWhenEncodedSemicolonInRequestUriThenThrowsRequestRejectedException() { |
||||
this.request.setRequestURI("/path%3B/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test(expected = RequestRejectedException.class) |
||||
public void getFirewalledRequestWhenLowercaseEncodedSemicolonInContextPathThenThrowsRequestRejectedException() { |
||||
this.request.setContextPath("%3b/context"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test(expected = RequestRejectedException.class) |
||||
public void getFirewalledRequestWhenLowercaseEncodedSemicolonInServletPathThenThrowsRequestRejectedException() { |
||||
this.request.setServletPath("/spring%3b/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test(expected = RequestRejectedException.class) |
||||
public void getFirewalledRequestWhenLowercaseEncodedSemicolonInPathInfoThenThrowsRequestRejectedException() { |
||||
this.request.setPathInfo("/path%3b/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test(expected = RequestRejectedException.class) |
||||
public void getFirewalledRequestWhenLowercaseEncodedSemicolonInRequestUriThenThrowsRequestRejectedException() { |
||||
this.request.setRequestURI("/path%3b/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenSemicolonInContextPathAndAllowSemicolonThenNoException() { |
||||
this.firewall.setAllowSemicolon(true); |
||||
this.request.setContextPath(";/context"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenSemicolonInServletPathAndAllowSemicolonThenNoException() { |
||||
this.firewall.setAllowSemicolon(true); |
||||
this.request.setServletPath("/spring;/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenSemicolonInPathInfoAndAllowSemicolonThenNoException() { |
||||
this.firewall.setAllowSemicolon(true); |
||||
this.request.setPathInfo("/path;/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenSemicolonInRequestUriAndAllowSemicolonThenNoException() { |
||||
this.firewall.setAllowSemicolon(true); |
||||
this.request.setRequestURI("/path;/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenEncodedSemicolonInContextPathAndAllowSemicolonThenNoException() { |
||||
this.firewall.setAllowUrlEncodedPercent(true); |
||||
this.firewall.setAllowSemicolon(true); |
||||
this.request.setContextPath("%3B/context"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenEncodedSemicolonInServletPathAndAllowSemicolonThenNoException() { |
||||
this.firewall.setAllowUrlEncodedPercent(true); |
||||
this.firewall.setAllowSemicolon(true); |
||||
this.request.setServletPath("/spring%3B/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenEncodedSemicolonInPathInfoAndAllowSemicolonThenNoException() { |
||||
this.firewall.setAllowUrlEncodedPercent(true); |
||||
this.firewall.setAllowSemicolon(true); |
||||
this.request.setPathInfo("/path%3B/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenEncodedSemicolonInRequestUriAndAllowSemicolonThenNoException() { |
||||
this.firewall.setAllowSemicolon(true); |
||||
this.request.setRequestURI("/path%3B/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenLowercaseEncodedSemicolonInContextPathAndAllowSemicolonThenNoException() { |
||||
this.firewall.setAllowUrlEncodedPercent(true); |
||||
this.firewall.setAllowSemicolon(true); |
||||
this.request.setContextPath("%3b/context"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenLowercaseEncodedSemicolonInServletPathAndAllowSemicolonThenNoException() { |
||||
this.firewall.setAllowUrlEncodedPercent(true); |
||||
this.firewall.setAllowSemicolon(true); |
||||
this.request.setServletPath("/spring%3b/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenLowercaseEncodedSemicolonInPathInfoAndAllowSemicolonThenNoException() { |
||||
this.firewall.setAllowUrlEncodedPercent(true); |
||||
this.firewall.setAllowSemicolon(true); |
||||
this.request.setPathInfo("/path%3b/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenLowercaseEncodedSemicolonInRequestUriAndAllowSemicolonThenNoException() { |
||||
this.firewall.setAllowSemicolon(true); |
||||
this.request.setRequestURI("/path%3b/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
// --- encoded . ---
|
||||
|
||||
@Test(expected = RequestRejectedException.class) |
||||
public void getFirewalledRequestWhenEncodedPeriodInThenThrowsRequestRejectedException() { |
||||
this.request.setRequestURI("/%2E/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test(expected = RequestRejectedException.class) |
||||
public void getFirewalledRequestWhenLowercaseEncodedPeriodInThenThrowsRequestRejectedException() { |
||||
this.request.setRequestURI("/%2e/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenAllowEncodedPeriodAndEncodedPeriodInThenNoException() { |
||||
this.firewall.setAllowUrlEncodedPeriod(true); |
||||
this.request.setRequestURI("/%2E/"); |
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
// --- from DefaultHttpFirewallTests ---
|
||||
|
||||
/** |
||||
* On WebSphere 8.5 a URL like /context-root/a/b;%2f1/c can bypass a rule on |
||||
* /a/b/c because the pathInfo is /a/b;/1/c which ends up being /a/b/1/c |
||||
* while Spring MVC will strip the ; content from requestURI before the path |
||||
* is URL decoded. |
||||
*/ |
||||
@Test(expected = RequestRejectedException.class) |
||||
public void getFirewalledRequestWhenLowercaseEncodedPathThenException() { |
||||
this.request.setRequestURI("/context-root/a/b;%2f1/c"); |
||||
this.request.setContextPath("/context-root"); |
||||
this.request.setServletPath(""); |
||||
this.request.setPathInfo("/a/b;/1/c"); // URL decoded requestURI
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test(expected = RequestRejectedException.class) |
||||
public void getFirewalledRequestWhenUppercaseEncodedPathThenException() { |
||||
this.request.setRequestURI("/context-root/a/b;%2F1/c"); |
||||
this.request.setContextPath("/context-root"); |
||||
this.request.setServletPath(""); |
||||
this.request.setPathInfo("/a/b;/1/c"); // URL decoded requestURI
|
||||
|
||||
this.firewall.getFirewalledRequest(this.request); |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenAllowUrlEncodedSlashAndLowercaseEncodedPathThenNoException() { |
||||
this.firewall.setAllowUrlEncodedSlash(true); |
||||
this.firewall.setAllowSemicolon(true); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(); |
||||
request.setRequestURI("/context-root/a/b;%2f1/c"); |
||||
request.setContextPath("/context-root"); |
||||
request.setServletPath(""); |
||||
request.setPathInfo("/a/b;/1/c"); // URL decoded requestURI
|
||||
|
||||
this.firewall.getFirewalledRequest(request); |
||||
} |
||||
|
||||
@Test |
||||
public void getFirewalledRequestWhenAllowUrlEncodedSlashAndUppercaseEncodedPathThenNoException() { |
||||
this.firewall.setAllowUrlEncodedSlash(true); |
||||
this.firewall.setAllowSemicolon(true); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(); |
||||
request.setRequestURI("/context-root/a/b;%2F1/c"); |
||||
request.setContextPath("/context-root"); |
||||
request.setServletPath(""); |
||||
request.setPathInfo("/a/b;/1/c"); // URL decoded requestURI
|
||||
|
||||
this.firewall.getFirewalledRequest(request); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue