最近项目在做安全漏洞扫描,结果报告中有关于 远端WWW服务支持TRACE请求漏洞。
RFC 2616介绍了TRACE请求,该请求典型地用于测试HTTP协议实现。攻击者利用TRACE请求,结合其它浏览器端漏洞,有可能进行跨站脚本攻击,获取敏感信息,比如cookie中的认证信息,这些敏感信息将被用于其它类型的攻击。
虽然不是什么高危漏洞,但还是存在风险。话不多说直接上解决代码。
模拟确认: 指令 curl -v -X TRACE localhost:port
C:\Users\z1777>curl -v -X TRACE http://127.0.0.1:7692 * Trying 127.0.0.1:7692... * Connected to 127.0.0.1 (127.0.0.1) port 7692 (#0) > TRACE / HTTP/1.1 > Host: 127.0.0.1:7692 > User-Agent: curl/8.0.1 > Accept: */* > < HTTP/1.1 200 OK < Connection: keep-alive < Content-Type: message/http < Content-Length: 77 < Date: Wed, 09 Aug 2023 09:18:57 GMT < TRACE / HTTP/1.1 Accept: */* User-Agent: curl/8.0.1 Host: 127.0.0.1:7692 * Connection #0 to host 127.0.0.1 left intact
响应返回 HTTP/1.1 200 OK,存在漏洞。
如果回显为,如下所示,则该漏洞不存在。
C:\Users\z1777>curl -v -X TRACE http://127.0.0.1:7778 * Trying 127.0.0.1:7778... * Connected to 127.0.0.1 (127.0.0.1) port 7778 (#0) > TRACE / HTTP/1.1 > Host: 127.0.0.1:7778 > User-Agent: curl/8.0.1 > Accept: */* > < HTTP/1.1 405 Method Not Allowed < Connection: keep-alive < Content-Type: message/http < Content-Length: 82 < Date: Wed, 09 Aug 2023 09:13:55 GMT < TRACE /error HTTP/1.1 Accept: */* User-Agent: curl/8.0.1 Host: 127.0.0.1:7778 * Connection #0 to host 127.0.0.1 left intact
解决方式大概分为两种:
通过过滤器的方式:
import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Component public class Filter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) { try { if (req.getMethod().equals("TRACE")) { res.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED); } else { filterChain.doFilter(req, res); } } catch(Exception e){} } }
通过spring boot内嵌tomcat的方式:
import org.apache.tomcat.util.descriptor.web.SecurityCollection; import org.apache.tomcat.util.descriptor.web.SecurityConstraint; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /* * http各种请求方式拦截 */ @Configuration public class HttpModeConfig { @Value("${spring.profiles.active}") String active; @Bean public ConfigurableServletWebServerFactory configurableServletWebServerFactory() { TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); factory.addContextCustomizers(context -> { SecurityConstraint securityConstraint = new SecurityConstraint(); securityConstraint.setUserConstraint("CONFIDENTIAL"); SecurityCollection collection = new SecurityCollection(); collection.addPattern("/*"); collection.addMethod("HEAD"); collection.addMethod("PUT"); collection.addMethod("DELETE"); //生产环境需要关闭options,浏览器测试需要options if ("prod".equals(active)){ collection.addMethod("OPTIONS"); } collection.addMethod("TRACE"); collection.addMethod("COPY"); collection.addMethod("SEARCH"); collection.addMethod("PROPFIND"); securityConstraint.addCollection(collection); securityConstraint.setAuthConstraint(true); context.addConstraint(securityConstraint); context.setUseHttpOnly(true); }); // 如果需要禁用TRACE请求,需添加以下代码: factory.addConnectorCustomizers(connector -> { connector.setAllowTrace(true); }); return factory; } }
提示:实践过程中,发现内置Tomcat解决方式和webSocket有冲突,服务启动会报 ServerEndpointExporter找不到。暂时没有好的解决办法,后面使用过滤器的方式实现。
spring配置文件方式:
在配置application.yml时,设置port-head
提示:网上找到的说是可以,但配置了没撒效果。
spring: tomcat: port-header: HEAD,PUT,DELETE,OPTIONS,TRACE,COPY,SEARCH,PROPFIND