spring-security: fix malicious char detection on StrictHttpFirewallFuzzer (#8630)

This commit is contained in:
Patrice.S 2022-09-29 19:10:00 +02:00 committed by GitHub
parent 31a99be20d
commit e381ee8ea1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 10 additions and 9 deletions

View File

@ -29,14 +29,12 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.lang.IllegalStateException;
public class StrictHttpFirewallFuzzer { public class StrictHttpFirewallFuzzer {
record Header(String n, String v) {}; record Header(String n, String v) {};
// https://github.com/spring-projects/spring-security/blob/main/web/src/main/java/org/springframework/security/web/firewall/StrictHttpFirewall.java#L127
private static Pattern ASSIGNED_AND_NOT_ISO_CONTROL_PATTERN = Pattern.compile("[\\p{IsAssigned}||[\\p{IsControl}]]*");
private static Predicate<String> ASSIGNED_AND_NOT_ISO_CONTROL_PREDICATE = (s) -> ASSIGNED_AND_NOT_ISO_CONTROL_PATTERN.matcher(s).matches();
public static void fuzzerTestOneInput(FuzzedDataProvider data) throws Exception { public static void fuzzerTestOneInput(FuzzedDataProvider data) throws Exception {
StrictHttpFirewall firewall = new StrictHttpFirewall(); StrictHttpFirewall firewall = new StrictHttpFirewall();
MockHttpServletRequest request = new MockHttpServletRequest("GET", ""); MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
@ -72,7 +70,7 @@ public class StrictHttpFirewallFuzzer {
maliciousUrls.add(url); maliciousUrls.add(url);
break; break;
case 4: case 4:
String parameterName = data.consumeAsciiString(100).trim(); String parameterName = data.consumeString(100);
if (parameterName.isEmpty()) { if (parameterName.isEmpty()) {
break; break;
} }
@ -102,7 +100,7 @@ public class StrictHttpFirewallFuzzer {
servletRequest.getParameter(parameterName); servletRequest.getParameter(parameterName);
} }
} catch (RequestRejectedException e) { } catch (RequestRejectedException | IllegalStateException e) {
return; return;
} }
@ -126,10 +124,13 @@ public class StrictHttpFirewallFuzzer {
} }
} }
// Wrapper for validateAllowedHeaderName, validateAllowedHeaderValue, validateAllowedParameterName & validateAllowedParameterValue // Check for invalid chars
// https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/firewall/StrictHttpFirewall.html#setAllowedHeaderNames(java.util.function.Predicate)
private static void validate(String value) { private static void validate(String value) {
if (!value.isEmpty() && ASSIGNED_AND_NOT_ISO_CONTROL_PREDICATE.test(value)) { for (char c : value.toCharArray()) {
throw new FuzzerSecurityIssueMedium("Malicious char not filtered: " + value); if (Character.isISOControl(c) || !Character.isDefined(c)) {
throw new FuzzerSecurityIssueMedium("Malicious char not filtered: \\x" + String.format("%04x", (int) c) + " in `" + value + "`");
}
} }
} }
} }