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

  1. Identify the blocked string from the exception message and fix the client/URL to avoid it (e.g. encode or rename the resource).
  2. If a legitimate resource collides with a blocklist entry (e.g. filenames containing '..'), rename the resource or path instead of removing blocklist entries.
  3. Check proxy configuration for double-encoding that produces encoded traversal sequences in the forwarded URL.
  4. 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

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.

Related errors


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)