spring-projects/spring-security · error · ServerExchangeRejectedException
The request was rejected because the URL contained a…
Error message
The request was rejected because the URL contained a potentially malicious String "<forbidden>"
What it means
StrictServerWebExchangeFirewall maintains encoded and decoded URL blocklists containing path-traversal patterns (e.g. %2e%2e, .., //, %2f). rejectedBlocklistedUrls iterates these lists and throws ServerExchangeRejectedException as soon as the request's encoded or decoded URL contains any forbidden string. This blocks traversal and URL-obfuscation payloads before filters run.
Solutions
- Identify the blocked string from the exception message and fix the client/URL to avoid it (e.g. encode or rename the resource).
- If a legitimate resource collides with a blocklist entry (e.g. filenames containing '..'), rename the resource or path instead of removing blocklist entries.
- Check proxy configuration for double-encoding that produces encoded traversal sequences in the forwarded URL.
- Only remove entries from the blocklist (removeFromUrlBlocklist) with a documented reason — they exist to block known attack payloads.
Example fix
// before
// GET /files/report..final.pdf -> matches blocklist ".."
// after
// GET /files/report-final.pdf
// or encode a search term:
const url = `/api/search?q=${encodeURIComponent(userInput)}`; Defensive patterns
Strategy: validation
Validate before calling
// Client-side guard before sending
String[] blocked = {"..", "%2e", "%2f", "//", ";"};
for (String b : blocked) {
if (url.toLowerCase().contains(b)) {
throw new IllegalArgumentException("URL contains blocked sequence: " + b);
}
} Try / catch
@ExceptionHandler(ServerExchangeRejectedException.class)
Mono<Void> handle(ServerWebExchange exchange, ServerExchangeRejectedException e) {
log.warn("Blocklisted URL rejected: {}", e.getMessage());
exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
return exchange.getResponse().setComplete();
} Prevention
- Never place user input directly into path segments — encode it
- Avoid filenames and IDs containing '..' or ';'
- Ensure proxies do not double-encode forwarded URLs
- Keep blocklist entries intact; fix URLs rather than weakening the blocklist
When it happens
Trigger: A request URL (raw/encoded or decoded) contains a blocklisted substring such as "..", "%2e", "%2f", "//", or ";" — typically traversal or injection probes — detected while firewalling the exchange.
Common situations: Security scanners and bots probing for traversal vulnerabilities; legitimate URLs that incidentally contain blocked substrings (e.g. ".." inside a filename or search term); misconfigured proxies double-encoding path segments; custom blocklist entries added too broadly.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- The request was rejected because the URL was not normalized
- The request was rejected because the HTTP method
- The was rejected because it can only contain printable…
- Invalid Authorization Grant Type
- invalid_token
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/aa7dd04132555019.
Report an issue: GitHub.
Appendix: source
Thrown at web/src/main/java/org/springframework/security/web/server/firewall/StrictServerWebExchangeFirewall.java:586
.format("The %s was rejected because it can only contain printable ASCII characters.", propertyName));
}
}
private void rejectForbiddenHttpMethod(ServerHttpRequest request) {
if (this.allowedHttpMethods == ALLOW_ANY_HTTP_METHOD) {
return;
}
if (!this.allowedHttpMethods.contains(request.getMethod())) {
throw new ServerExchangeRejectedException(
"The request was rejected because the HTTP method \"" + request.getMethod()
+ "\" was not included within the list of allowed HTTP methods " + this.allowedHttpMethods);
}
}
private void rejectedBlocklistedUrls(ServerHttpRequest request) {
for (String forbidden : this.encodedUrlBlocklist) {
if (encodedUrlContains(request, forbidden)) {
throw new ServerExchangeRejectedException(
"The request was rejected because the URL contained a potentially malicious String \""
+ forbidden + "\"");
}
}
for (String forbidden : this.decodedUrlBlocklist) {
if (decodedUrlContains(request, forbidden)) {
throw new ServerExchangeRejectedException(
"The request was rejected because the URL contained a potentially malicious String \""
+ forbidden + "\"");
}
}
}
private void rejectedUntrustedHosts(ServerHttpRequest request) {
String hostName = request.getURI().getHost();
if (hostName != null && !this.allowedHostnames.test(hostName)) {
throw new ServerExchangeRejectedException(
"The request was rejected because the domain " + hostName + " is untrusted.");View on GitHub (pinned to 96852e8860)