Skip to content

Commit 4405cf1

Browse files
committed
Extract rejectNonPrintableAsciiCharactersInFieldName
Closes gh-11234
1 parent 7eb8a58 commit 4405cf1

File tree

2 files changed

+42
-5
lines changed

2 files changed

+42
-5
lines changed

web/src/main/java/org/springframework/security/web/firewall/StrictHttpFirewall.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -431,14 +431,20 @@ public FirewalledRequest getFirewalledRequest(HttpServletRequest request) throws
431431
if (!isNormalized(request)) {
432432
throw new RequestRejectedException("The request was rejected because the URL was not normalized.");
433433
}
434-
String requestUri = request.getRequestURI();
435-
if (!containsOnlyPrintableAsciiCharacters(requestUri)) {
436-
throw new RequestRejectedException(
437-
"The requestURI was rejected because it can only contain printable ASCII characters.");
438-
}
434+
rejectNonPrintableAsciiCharactersInFieldName(request.getRequestURI(), "requestURI");
435+
rejectNonPrintableAsciiCharactersInFieldName(request.getServletPath(), "servletPath");
436+
rejectNonPrintableAsciiCharactersInFieldName(request.getPathInfo(), "pathInfo");
437+
rejectNonPrintableAsciiCharactersInFieldName(request.getContextPath(), "contextPath");
439438
return new StrictFirewalledRequest(request);
440439
}
441440

441+
private void rejectNonPrintableAsciiCharactersInFieldName(String toCheck, String propertyName) {
442+
if (!containsOnlyPrintableAsciiCharacters(toCheck)) {
443+
throw new RequestRejectedException(String.format(
444+
"The %s was rejected because it can only contain printable ASCII characters.", propertyName));
445+
}
446+
}
447+
442448
private void rejectForbiddenHttpMethod(HttpServletRequest request) {
443449
if (this.allowedHttpMethods == ALLOW_ANY_HTTP_METHOD) {
444450
return;
@@ -526,6 +532,9 @@ private static boolean decodedUrlContains(HttpServletRequest request, String val
526532
}
527533

528534
private static boolean containsOnlyPrintableAsciiCharacters(String uri) {
535+
if (uri == null) {
536+
return true;
537+
}
529538
int length = uri.length();
530539
for (int i = 0; i < length; i++) {
531540
char ch = uri.charAt(i);

web/src/test/java/org/springframework/security/web/firewall/StrictHttpFirewallTests.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,34 @@ public void getFirewalledRequestWhenContainsEncodedNullThenException() {
364364
.isThrownBy(() -> this.firewall.getFirewalledRequest(this.request));
365365
}
366366

367+
@Test
368+
public void getFirewalledRequestWhenContainsLineFeedThenException() {
369+
this.request.setRequestURI("/something\n/");
370+
assertThatExceptionOfType(RequestRejectedException.class)
371+
.isThrownBy(() -> this.firewall.getFirewalledRequest(this.request));
372+
}
373+
374+
@Test
375+
public void getFirewalledRequestWhenServletPathContainsLineFeedThenException() {
376+
this.request.setServletPath("/something\n/");
377+
assertThatExceptionOfType(RequestRejectedException.class)
378+
.isThrownBy(() -> this.firewall.getFirewalledRequest(this.request));
379+
}
380+
381+
@Test
382+
public void getFirewalledRequestWhenContainsCarriageReturnThenException() {
383+
this.request.setRequestURI("/something\r/");
384+
assertThatExceptionOfType(RequestRejectedException.class)
385+
.isThrownBy(() -> this.firewall.getFirewalledRequest(this.request));
386+
}
387+
388+
@Test
389+
public void getFirewalledRequestWhenServletPathContainsCarriageReturnThenException() {
390+
this.request.setServletPath("/something\r/");
391+
assertThatExceptionOfType(RequestRejectedException.class)
392+
.isThrownBy(() -> this.firewall.getFirewalledRequest(this.request));
393+
}
394+
367395
/**
368396
* On WebSphere 8.5 a URL like /context-root/a/b;%2f1/c can bypass a rule on /a/b/c
369397
* because the pathInfo is /a/b;/1/c which ends up being /a/b/1/c while Spring MVC

0 commit comments

Comments
 (0)