spring-projects/spring-security · error · RequestRejectedException

The requestURI cannot contain encoded slash. Got " +…

Error message

The requestURI cannot contain encoded slash. Got " + requestURI

What it means

DefaultHttpFirewall rejects a request whose requestURI contains an URL-encoded slash (%2F or lowercase variants) that would decode into a path separator. Because decoding happens later in the container, an encoded slash could smuggle extra path segments past URL-pattern based authorization. It throws RequestRejectedException with the offending URI.

Solutions

  1. Have clients use double-encoded slashes (%252F) or restructure identifiers to avoid slashes (use IDs instead of names containing '/')
  2. If encoded slashes are legitimate for your app, call firewall.setAllowUrlEncodedSlash(true) on the DefaultHttpFirewall bean (and matching Tomcat system property org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true / relaxedPathChars as needed)
  3. Decode/normalize at the reverse proxy before forwarding, or map such requests to a different route pattern
  4. Verify which firewall bean FilterChainProxy uses; prefer StrictHttpFirewall and configure setAllowUrlEncodedSlash there with full awareness of the bypass risk

Example fix

// before
@Bean
DefaultHttpFirewall firewall() { return new DefaultHttpFirewall(); }
// after
@Bean
DefaultHttpFirewall firewall() {
    DefaultHttpFirewall fw = new DefaultHttpFirewall();
    fw.setAllowUrlEncodedSlash(true); // only if encoded slashes are required and safe here
    return fw;
}
Defensive patterns

Strategy: try-catch

Validate before calling

String uri = request.getRequestURI();
boolean hasEncodedSlash = uri.toLowerCase().contains("%2f");
if (hasEncodedSlash && !allowEncodedSlash) {
    // reject or re-encode client-side before calling the firewall
}

Try / catch

try {
    FirewalledRequest fw = firewall.getFirewalledRequest(request);
    chain.doFilter(fw, response);
} catch (RequestRejectedException e) {
    if (e.getMessage().contains("encoded slash")) {
        response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Encoded slashes are not allowed");
    } else throw e;
}

Prevention

When it happens

Trigger: A client sends a requestURI containing %2F or %2f (e.g. /api/resource%2Fsub) and the URI contains no valid, permitted encoded slash — DefaultHttpFirewall strictly rejects encoded slashes unless allowUrlEncodedSlash is set (and even then only for non-blocking cases per release).

Common situations: REST APIs where resource identifiers contain slashes and clients pre-encode them; gateway already decoded once then re-encoded (%252F double encoding); frontend routing frameworks generating encoded path segments; upgrading Spring Security changed firewall behavior for paths that previously worked.

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/638506a00a276194. Report an issue: GitHub.

Appendix: source

Thrown at web/src/main/java/org/springframework/security/web/firewall/DefaultHttpFirewall.java:61

 *
 * @author Luke Taylor
 * @see StrictHttpFirewall
 */
public class DefaultHttpFirewall implements HttpFirewall {

	private boolean allowUrlEncodedSlash;

	@Override
	public FirewalledRequest getFirewalledRequest(HttpServletRequest request) throws RequestRejectedException {
		FirewalledRequest firewalledRequest = new RequestWrapper(request);
		if (!isNormalized(firewalledRequest.getServletPath()) || !isNormalized(firewalledRequest.getPathInfo())) {
			throw new RequestRejectedException(
					"Un-normalized paths are not supported: " + firewalledRequest.getServletPath()
							+ ((firewalledRequest.getPathInfo() != null) ? firewalledRequest.getPathInfo() : ""));
		}
		String requestURI = firewalledRequest.getRequestURI();
		if (containsInvalidUrlEncodedSlash(requestURI)) {
			throw new RequestRejectedException("The requestURI cannot contain encoded slash. Got " + requestURI);
		}
		return firewalledRequest;
	}

	@Override
	public HttpServletResponse getFirewalledResponse(HttpServletResponse response) {
		return new FirewalledResponse(response);
	}

	/**
	 * <p>
	 * Sets if the application should allow a URL encoded slash character.
	 * </p>
	 * <p>
	 * If true (default is false), a URL encoded slash will be allowed in the URL.
	 * Allowing encoded slashes can cause security vulnerabilities in some situations
	 * depending on how the container constructs the HttpServletRequest.
	 * </p>

View on GitHub (pinned to 96852e8860)