Skip to content

Commit 4169c0c

Browse files
baezzysjzheaux
authored andcommitted
Publish Constants for Firewall Header and Parameter Predicates
Introduced public static final Predicates for allowed header names, header values, parameter names, and parameter values for building expressions. Closes gh-13639
1 parent df76537 commit 4169c0c

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

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

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
*
7676
* @author Rob Winch
7777
* @author Eddú Meléndez
78+
* @author Jinwoo Bae
7879
* @since 4.2.4
7980
* @see DefaultHttpFirewall
8081
*/
@@ -134,13 +135,21 @@ public class StrictHttpFirewall implements HttpFirewall {
134135

135136
private static final Predicate<String> HEADER_VALUE_PREDICATE = (s) -> HEADER_VALUE_PATTERN.matcher(s).matches();
136137

137-
private Predicate<String> allowedHeaderNames = ASSIGNED_AND_NOT_ISO_CONTROL_PREDICATE;
138+
private Predicate<String> allowedHeaderNames = ALLOWED_HEADER_NAMES;
138139

139-
private Predicate<String> allowedHeaderValues = HEADER_VALUE_PREDICATE;
140+
public static final Predicate<String> ALLOWED_HEADER_NAMES = ASSIGNED_AND_NOT_ISO_CONTROL_PREDICATE;
140141

141-
private Predicate<String> allowedParameterNames = ASSIGNED_AND_NOT_ISO_CONTROL_PREDICATE;
142+
private Predicate<String> allowedHeaderValues = ALLOWED_HEADER_VALUES;
142143

143-
private Predicate<String> allowedParameterValues = (value) -> true;
144+
public static final Predicate<String> ALLOWED_HEADER_VALUES = HEADER_VALUE_PREDICATE;
145+
146+
private Predicate<String> allowedParameterNames = ALLOWED_PARAMETER_NAMES;
147+
148+
public static final Predicate<String> ALLOWED_PARAMETER_NAMES = ASSIGNED_AND_NOT_ISO_CONTROL_PREDICATE;
149+
150+
private Predicate<String> allowedParameterValues = ALLOWED_PARAMETER_VALUES;
151+
152+
public static final Predicate<String> ALLOWED_PARAMETER_VALUES = (value) -> true;
144153

145154
public StrictHttpFirewall() {
146155
urlBlocklistsAddAll(FORBIDDEN_SEMICOLON);

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
/**
3232
* @author Rob Winch
3333
* @author Eddú Meléndez
34+
* @author Jinwoo Bae
3435
*/
3536
public class StrictHttpFirewallTests {
3637

@@ -723,6 +724,14 @@ public void getFirewalledRequestGetHeaderWhenNotAllowedHeaderNameThenException()
723724
assertThatExceptionOfType(RequestRejectedException.class).isThrownBy(() -> request.getHeader("bad name"));
724725
}
725726

727+
@Test
728+
public void getFirewalledRequestWhenHeaderNameNotAllowedWithAugmentedHeaderNamesThenException() {
729+
this.firewall
730+
.setAllowedHeaderNames(StrictHttpFirewall.ALLOWED_HEADER_NAMES.and((name) -> !name.equals("bad name")));
731+
HttpServletRequest request = this.firewall.getFirewalledRequest(this.request);
732+
assertThatExceptionOfType(RequestRejectedException.class).isThrownBy(() -> request.getHeader("bad name"));
733+
}
734+
726735
@Test
727736
public void getFirewalledRequestGetHeaderWhenNotAllowedHeaderValueThenException() {
728737
this.request.addHeader("good name", "bad value");
@@ -731,6 +740,15 @@ public void getFirewalledRequestGetHeaderWhenNotAllowedHeaderValueThenException(
731740
assertThatExceptionOfType(RequestRejectedException.class).isThrownBy(() -> request.getHeader("good name"));
732741
}
733742

743+
@Test
744+
public void getFirewalledRequestWhenHeaderValueNotAllowedWithAugmentedHeaderValuesThenException() {
745+
this.request.addHeader("good name", "bad value");
746+
this.firewall.setAllowedHeaderValues(
747+
StrictHttpFirewall.ALLOWED_HEADER_VALUES.and((value) -> !value.equals("bad value")));
748+
HttpServletRequest request = this.firewall.getFirewalledRequest(this.request);
749+
assertThatExceptionOfType(RequestRejectedException.class).isThrownBy(() -> request.getHeader("good name"));
750+
}
751+
734752
@Test
735753
public void getFirewalledRequestGetDateHeaderWhenControlCharacterInHeaderNameThenException() {
736754
this.request.addHeader("Bad\0Name", "some value");
@@ -840,6 +858,16 @@ public void getFirewalledRequestGetParameterValuesWhenNotAllowedInParameterValue
840858
.isThrownBy(() -> request.getParameterValues("Something"));
841859
}
842860

861+
@Test
862+
public void getFirewalledRequestWhenParameterValueNotAllowedWithAugmentedParameterValuesThenException() {
863+
this.request.addParameter("Something", "bad value");
864+
this.firewall.setAllowedParameterValues(
865+
StrictHttpFirewall.ALLOWED_PARAMETER_VALUES.and((value) -> !value.equals("bad value")));
866+
HttpServletRequest request = this.firewall.getFirewalledRequest(this.request);
867+
assertThatExceptionOfType(RequestRejectedException.class)
868+
.isThrownBy(() -> request.getParameterValues("Something"));
869+
}
870+
843871
@Test
844872
public void getFirewalledRequestGetParameterValuesWhenNotAllowedInParameterNameThenException() {
845873
this.firewall.setAllowedParameterNames((value) -> !value.equals("bad name"));
@@ -849,6 +877,16 @@ public void getFirewalledRequestGetParameterValuesWhenNotAllowedInParameterNameT
849877
.isThrownBy(() -> request.getParameterValues("bad name"));
850878
}
851879

880+
@Test
881+
public void getFirewalledRequestWhenParameterNameNotAllowedWithAugmentedParameterNamesThenException() {
882+
this.request.addParameter("bad name", "good value");
883+
this.firewall.setAllowedParameterNames(
884+
StrictHttpFirewall.ALLOWED_PARAMETER_NAMES.and((value) -> !value.equals("bad name")));
885+
HttpServletRequest request = this.firewall.getFirewalledRequest(this.request);
886+
assertThatExceptionOfType(RequestRejectedException.class)
887+
.isThrownBy(() -> request.getParameterValues("bad name"));
888+
}
889+
852890
// gh-9598
853891
@Test
854892
public void getFirewalledRequestGetParameterWhenNameIsNullThenIllegalArgumentException() {

0 commit comments

Comments
 (0)