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

SpringBoot内嵌Tomcat Allow头硬编码致漏洞 如何仅开放GET/POST方法

SpringBoot OPTIONS *请求Allow响应头硬编码问题修复方案

问题背景

  • 对SpringBoot应用开展渗透测试过程中,检测到两项HTTP方法配置相关安全风险。
  • 执行nikto扫描命令nikto -ssl -h https://localhost:8181返回如下告警:
+ Allowed HTTP Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS 
+ OSVDB-397: HTTP method ('Allow' Header): 'PUT' method could allow clients to save files on the web server.
+ OSVDB-5646: HTTP method ('Allow' Header): 'DELETE' may allow clients to remove files on the web server.
  • 执行curl探测命令curl -k -i --request-target "*" -X OPTIONS https://localhost:8181可稳定复现该问题,响应头中Allow字段值固定为GET, HEAD, POST, PUT, DELETE, OPTIONS。
  • 此前尝试调整SpringBoot常规配置,目标是让响应头仅返回Allow: GET, POST,但未达到预期效果。
  • 源码排查确认:针对OPTIONS *请求的处理逻辑位于Tomcat的CoyoteAdapter类中,核心代码片段如下:
protected boolean postParseRequest(org.apache.coyote.Request req,
                                       Request request,
                                       org.apache.coyote.Response res,
                                       Response response) throws IOException, ServletException {
    ...
        if (undecodedURI.equals("*")) {
            if (req.method().equalsIgnoreCase("OPTIONS")) {
                StringBuilder allow = new StringBuilder();
                allow.append("GET, HEAD, POST, PUT, DELETE, OPTIONS");
  • 该处Allow字段值为Tomcat底层硬编码实现,无法通过Spring常规配置修改,需要可落地的方案规避该类漏洞检测。

备注:本问题为两个同主题Spring Web应用HTTP方法限制问题的后续延伸,核心诉求是覆盖全场景将应用对外允许的HTTP方法限制为GET、POST。

可行解决方案

方案1:应用层添加Servlet过滤器拦截重写响应头

该方案侵入性最低,无需修改Tomcat底层逻辑,仅需在应用中新增自定义过滤器,匹配到OPTIONS *请求时直接覆盖Allow响应头即可,示例代码如下:

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter(filterName = "allowMethodRewriteFilter", urlPatterns = "/*")
public class AllowMethodRewriteFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpReq = (HttpServletRequest) request;
        HttpServletResponse httpResp = (HttpServletResponse) response;
        // 匹配OPTIONS *请求
        if ("OPTIONS".equalsIgnoreCase(httpReq.getMethod()) && "*".equals(httpReq.getRequestURI())) {
            httpResp.reset();
            httpResp.setHeader("Allow", "GET, POST");
            httpResp.setStatus(HttpServletResponse.SC_OK);
            return;
        }
        chain.doFilter(request, response);
    }
}

适配说明:SpringBoot 2.x版本使用javax.servlet包,将上述代码中jakarta开头的包路径替换为javax即可;启动类需要添加@ServletComponentScan注解以扫描注册该过滤器。

方案2:自定义Tomcat适配器替换硬编码逻辑

如果不希望在过滤器链路增加额外处理逻辑,可以自定义CoyoteAdapter子类,重写postParseRequest方法中拼接Allow字段的逻辑,再通过TomcatServletWebServerFactory将自定义适配器注册到Tomcat容器中,替换原有硬编码实现。

方案3:前置网关层拦截修改响应

如果应用前端部署了Nginx、API网关等反向代理组件,可以直接在网关层匹配OPTIONS *请求,直接返回自定义的Allow响应头,无需修改任何应用代码,Nginx配置示例如下:

server {
    listen 8181 ssl;
    # 省略SSL证书、域名等基础配置
    location / {
        if ($request_method = OPTIONS) {
            if ($request_uri = "*") {
                add_header Allow "GET, POST" always;
                return 200;
            }
        }
        proxy_pass http://后端SpringBoot应用服务地址;
    }
}

风险补充说明:Tomcat硬编码返回PUT、DELETE方法仅为OPTIONS探测响应的默认值,只要Spring侧没有配置对应路径的PUT/DELETE接口映射,攻击者无法实际调用这些方法执行文件上传、删除操作,Nikto的告警属于配置类风险提示,确认无对应危险接口暴露的情况下不存在可直接利用的实际漏洞。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 02:09:39