HTTP firewall validates incoming requests and rejects potentially malicious requests to protect against various attacks.
Validates requests and provides wrapped request/response objects.
package org.springframework.security.web.firewall;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public interface HttpFirewall {
/**
* Returns a wrapped request after validation.
*
* @param request the original request
* @return the firewalled request
* @throws RequestRejectedException if request is rejected
*/
FirewalledRequest getFirewalledRequest(HttpServletRequest request)
throws RequestRejectedException;
/**
* Returns a wrapped response.
*
* @param response the original response
* @return the firewalled response
*/
HttpServletResponse getFirewalledResponse(HttpServletResponse response);
}Wrapped HTTP request that has passed firewall validation.
package org.springframework.security.web.firewall;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
public interface FirewalledRequest extends HttpServletRequest {
/**
* Resets the request to original state.
*/
void reset();
}Wrapped HTTP response that has passed firewall validation.
package org.springframework.security.web.firewall;
import jakarta.servlet.http.HttpServletResponse;
public interface FirewalledResponse extends HttpServletResponse {
/**
* Marker interface for responses that have been validated by the firewall.
* No additional methods beyond HttpServletResponse.
*/
}Strict HTTP firewall that rejects suspicious requests.
package org.springframework.security.web.firewall;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.List;
public class StrictHttpFirewall implements HttpFirewall {
public StrictHttpFirewall();
public FirewalledRequest getFirewalledRequest(HttpServletRequest request)
throws RequestRejectedException;
public HttpServletResponse getFirewalledResponse(HttpServletResponse response);
/**
* Sets whether to allow semicolon in URLs (default: false).
*/
public void setAllowSemicolon(boolean allowSemicolon);
/**
* Sets whether to allow URL-encoded slash (default: false).
*/
public void setAllowUrlEncodedSlash(boolean allowUrlEncodedSlash);
/**
* Sets whether to allow URL-encoded percent (default: false).
*/
public void setAllowUrlEncodedPercent(boolean allowUrlEncodedPercent);
/**
* Sets whether to allow backslash (default: false).
*/
public void setAllowBackSlash(boolean allowBackSlash);
/**
* Sets whether to allow null bytes (default: false).
*/
public void setAllowNull(boolean allowNull);
/**
* Sets whether to allow URL-encoded period (default: false).
*/
public void setAllowUrlEncodedPeriod(boolean allowUrlEncodedPeriod);
/**
* Sets allowed HTTP methods.
* Default: DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT
*/
public void setAllowedHttpMethods(Collection<String> allowedHttpMethods);
/**
* Sets whether to allow any HTTP method (default: false).
*/
public void setUnsafeAllowAnyHttpMethod(boolean unsafeAllowAnyHttpMethod);
/**
* Sets allowed header names.
*/
public void setAllowedHeaderNames(Collection<String> allowedHeaderNames);
/**
* Sets allowed header values.
*/
public void setAllowedHeaderValues(Collection<String> allowedHeaderValues);
/**
* Sets allowed hostnames.
*/
public void setAllowedHostnames(Collection<String> allowedHostnames);
}Less strict firewall (deprecated in favor of StrictHttpFirewall).
package org.springframework.security.web.firewall;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@Deprecated
public class DefaultHttpFirewall implements HttpFirewall {
public DefaultHttpFirewall();
public FirewalledRequest getFirewalledRequest(HttpServletRequest request)
throws RequestRejectedException;
public HttpServletResponse getFirewalledResponse(HttpServletResponse response);
/**
* Sets whether to allow URL-encoded slash (default: false).
*/
public void setAllowUrlEncodedSlash(boolean allowUrlEncodedSlash);
}Thrown when a request is rejected by the firewall.
package org.springframework.security.web.firewall;
public class RequestRejectedException extends RuntimeException {
/**
* Creates an exception with a message.
*
* @param message the detail message
*/
public RequestRejectedException(String message);
/**
* Creates an exception with message and cause.
*/
public RequestRejectedException(String message, Throwable cause);
}Handles rejected requests.
package org.springframework.security.web.firewall;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public interface RequestRejectedHandler {
/**
* Handles a rejected request.
*
* @param request the HTTP request
* @param response the HTTP response
* @param requestRejectedException the rejection exception
*/
void handle(HttpServletRequest request, HttpServletResponse response,
RequestRejectedException requestRejectedException)
throws IOException, ServletException;
}Returns HTTP 400 Bad Request for rejected requests.
package org.springframework.security.web.firewall;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HttpStatusRequestRejectedHandler implements RequestRejectedHandler {
public HttpStatusRequestRejectedHandler();
public void handle(HttpServletRequest request, HttpServletResponse response,
RequestRejectedException requestRejectedException)
throws IOException, ServletException;
}Default handler that simply rethrows the RequestRejectedException.
package org.springframework.security.web.firewall;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public class DefaultRequestRejectedHandler implements RequestRejectedHandler {
public void handle(HttpServletRequest request, HttpServletResponse response,
RequestRejectedException requestRejectedException)
throws IOException, ServletException;
}Delegates to multiple request rejected handlers in sequence.
package org.springframework.security.web.firewall;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
public class CompositeRequestRejectedHandler implements RequestRejectedHandler {
/**
* Creates a composite handler with multiple delegates.
*
* @param requestRejectedHandlers the list of handlers to invoke
*/
public CompositeRequestRejectedHandler(RequestRejectedHandler... requestRejectedHandlers);
/**
* Invokes all handlers in order. The first handler to throw an exception
* stops the chain.
*/
public void handle(HttpServletRequest request, HttpServletResponse response,
RequestRejectedException requestRejectedException)
throws IOException, ServletException;
}import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.StrictHttpFirewall;
@Configuration
public class FirewallConfig {
@Bean
public HttpFirewall httpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowSemicolon(false);
firewall.setAllowUrlEncodedSlash(false);
firewall.setAllowBackSlash(false);
firewall.setAllowNull(false);
firewall.setAllowUrlEncodedPercent(false);
firewall.setAllowUrlEncodedPeriod(false);
return firewall;
}
}import org.springframework.security.web.firewall.RequestRejectedHandler;
import org.springframework.security.web.firewall.RequestRejectedException;
public class CustomRequestRejectedHandler implements RequestRejectedHandler {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
RequestRejectedException exception) throws IOException {
// Log the rejected request
logger.warn("Request rejected: {} {} from {}",
request.getMethod(),
request.getRequestURI(),
request.getRemoteAddr(),
exception
);
// Return custom error response
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.setContentType("application/json");
response.getWriter().write("{\"error\": \"Invalid request\"}");
}
}