Browse Source

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
pull/15443/head
baezzys 2 years ago committed by Josh Cummings
parent
commit
4169c0cf36
  1. 17
      web/src/main/java/org/springframework/security/web/firewall/StrictHttpFirewall.java
  2. 38
      web/src/test/java/org/springframework/security/web/firewall/StrictHttpFirewallTests.java

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

@ -75,6 +75,7 @@ import org.springframework.util.Assert; @@ -75,6 +75,7 @@ import org.springframework.util.Assert;
*
* @author Rob Winch
* @author Eddú Meléndez
* @author Jinwoo Bae
* @since 4.2.4
* @see DefaultHttpFirewall
*/
@ -134,13 +135,21 @@ public class StrictHttpFirewall implements HttpFirewall { @@ -134,13 +135,21 @@ public class StrictHttpFirewall implements HttpFirewall {
private static final Predicate<String> HEADER_VALUE_PREDICATE = (s) -> HEADER_VALUE_PATTERN.matcher(s).matches();
private Predicate<String> allowedHeaderNames = ASSIGNED_AND_NOT_ISO_CONTROL_PREDICATE;
private Predicate<String> allowedHeaderNames = ALLOWED_HEADER_NAMES;
private Predicate<String> allowedHeaderValues = HEADER_VALUE_PREDICATE;
public static final Predicate<String> ALLOWED_HEADER_NAMES = ASSIGNED_AND_NOT_ISO_CONTROL_PREDICATE;
private Predicate<String> allowedParameterNames = ASSIGNED_AND_NOT_ISO_CONTROL_PREDICATE;
private Predicate<String> allowedHeaderValues = ALLOWED_HEADER_VALUES;
private Predicate<String> allowedParameterValues = (value) -> true;
public static final Predicate<String> ALLOWED_HEADER_VALUES = HEADER_VALUE_PREDICATE;
private Predicate<String> allowedParameterNames = ALLOWED_PARAMETER_NAMES;
public static final Predicate<String> ALLOWED_PARAMETER_NAMES = ASSIGNED_AND_NOT_ISO_CONTROL_PREDICATE;
private Predicate<String> allowedParameterValues = ALLOWED_PARAMETER_VALUES;
public static final Predicate<String> ALLOWED_PARAMETER_VALUES = (value) -> true;
public StrictHttpFirewall() {
urlBlocklistsAddAll(FORBIDDEN_SEMICOLON);

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

@ -31,6 +31,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -31,6 +31,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Rob Winch
* @author Eddú Meléndez
* @author Jinwoo Bae
*/
public class StrictHttpFirewallTests {
@ -723,6 +724,14 @@ public class StrictHttpFirewallTests { @@ -723,6 +724,14 @@ public class StrictHttpFirewallTests {
assertThatExceptionOfType(RequestRejectedException.class).isThrownBy(() -> request.getHeader("bad name"));
}
@Test
public void getFirewalledRequestWhenHeaderNameNotAllowedWithAugmentedHeaderNamesThenException() {
this.firewall
.setAllowedHeaderNames(StrictHttpFirewall.ALLOWED_HEADER_NAMES.and((name) -> !name.equals("bad name")));
HttpServletRequest request = this.firewall.getFirewalledRequest(this.request);
assertThatExceptionOfType(RequestRejectedException.class).isThrownBy(() -> request.getHeader("bad name"));
}
@Test
public void getFirewalledRequestGetHeaderWhenNotAllowedHeaderValueThenException() {
this.request.addHeader("good name", "bad value");
@ -731,6 +740,15 @@ public class StrictHttpFirewallTests { @@ -731,6 +740,15 @@ public class StrictHttpFirewallTests {
assertThatExceptionOfType(RequestRejectedException.class).isThrownBy(() -> request.getHeader("good name"));
}
@Test
public void getFirewalledRequestWhenHeaderValueNotAllowedWithAugmentedHeaderValuesThenException() {
this.request.addHeader("good name", "bad value");
this.firewall.setAllowedHeaderValues(
StrictHttpFirewall.ALLOWED_HEADER_VALUES.and((value) -> !value.equals("bad value")));
HttpServletRequest request = this.firewall.getFirewalledRequest(this.request);
assertThatExceptionOfType(RequestRejectedException.class).isThrownBy(() -> request.getHeader("good name"));
}
@Test
public void getFirewalledRequestGetDateHeaderWhenControlCharacterInHeaderNameThenException() {
this.request.addHeader("Bad\0Name", "some value");
@ -840,6 +858,16 @@ public class StrictHttpFirewallTests { @@ -840,6 +858,16 @@ public class StrictHttpFirewallTests {
.isThrownBy(() -> request.getParameterValues("Something"));
}
@Test
public void getFirewalledRequestWhenParameterValueNotAllowedWithAugmentedParameterValuesThenException() {
this.request.addParameter("Something", "bad value");
this.firewall.setAllowedParameterValues(
StrictHttpFirewall.ALLOWED_PARAMETER_VALUES.and((value) -> !value.equals("bad value")));
HttpServletRequest request = this.firewall.getFirewalledRequest(this.request);
assertThatExceptionOfType(RequestRejectedException.class)
.isThrownBy(() -> request.getParameterValues("Something"));
}
@Test
public void getFirewalledRequestGetParameterValuesWhenNotAllowedInParameterNameThenException() {
this.firewall.setAllowedParameterNames((value) -> !value.equals("bad name"));
@ -849,6 +877,16 @@ public class StrictHttpFirewallTests { @@ -849,6 +877,16 @@ public class StrictHttpFirewallTests {
.isThrownBy(() -> request.getParameterValues("bad name"));
}
@Test
public void getFirewalledRequestWhenParameterNameNotAllowedWithAugmentedParameterNamesThenException() {
this.request.addParameter("bad name", "good value");
this.firewall.setAllowedParameterNames(
StrictHttpFirewall.ALLOWED_PARAMETER_NAMES.and((value) -> !value.equals("bad name")));
HttpServletRequest request = this.firewall.getFirewalledRequest(this.request);
assertThatExceptionOfType(RequestRejectedException.class)
.isThrownBy(() -> request.getParameterValues("bad name"));
}
// gh-9598
@Test
public void getFirewalledRequestGetParameterWhenNameIsNullThenIllegalArgumentException() {

Loading…
Cancel
Save