You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决Spring Security因含//的恶意URL抛出RequestRejectedException问题

解决Spring Security防火墙拦截恶意URL时的日志报错问题

你的核心问题是Spring Security的StrictHttpFirewall拦截含//的恶意URL后,会抛出RequestRejectedException并打印完整错误堆栈,但你希望保持拦截规则的同时,避免日志中出现错误级别的堆栈信息。由于Spring Security过滤器链优先级高于自定义过滤器,直接用自定义过滤器无法提前拦截,以下是两种可靠解决方案:

方案一:自定义RequestRejectedHandler(推荐)

通过实现Spring Security的RequestRejectedHandler接口,自定义异常处理逻辑,控制返回状态码和日志输出级别,既保留拦截能力,又避免错误堆栈刷屏。

代码实现

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.firewall.RequestRejectedException;
import org.springframework.security.web.firewall.RequestRejectedHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                // 这里添加你的其他安全配置(如授权、认证规则)
                .authorizeHttpRequests(auth -> auth.anyRequest().permitAll())
                // 配置自定义的请求拒绝处理器
                .exceptionHandling(exceptionConfig ->
                        exceptionConfig.requestRejectedHandler(customRequestRejectedHandler())
                );
        return http.build();
    }

    @Bean
    public RequestRejectedHandler customRequestRejectedHandler() {
        return new RequestRejectedHandler() {
            private final Logger logger = LoggerFactory.getLogger(getClass());

            @Override
            public void handle(HttpServletRequest request, HttpServletResponse response, RequestRejectedException ex) throws IOException, ServletException {
                // 返回404状态码,和你当前浏览器收到的一致
                response.sendError(HttpServletResponse.SC_NOT_FOUND);
                // 仅记录警告级别的日志,不打印完整堆栈
                logger.warn("拦截恶意请求: URL包含潜在危险字符 - 请求地址: {}", request.getRequestURI());
            }
        };
    }
}

方案二:调整日志级别(快速临时方案)

如果你不想编写自定义代码,可以直接调整Spring Security防火墙模块的日志级别,将其从ERROR改为WARN,这样就不会打印错误堆栈。

配置方式(Spring Boot)

在application.properties中添加:

logging.level.org.springframework.security.web.firewall=WARN

或者在application.yml中:

logging:
  level:
    org.springframework.security.web.firewall: WARN

注意:这种方式会将该包下所有日志降级为WARN级别,可能会忽略其他潜在的严重错误,因此仅推荐作为临时方案。

为什么自定义过滤器无效?

Spring Security的FilterChainProxy默认在所有自定义Servlet过滤器之前注册,请求会先经过Spring Security的防火墙校验,校验失败抛出异常后,请求根本不会到达你的自定义过滤器,因此必须通过Spring Security自身的异常处理机制来处理该异常。

内容的提问来源于stack exchange,提问作者inquisitive

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 16:13:21