漏洞名称 : OPTIONS method is enabled
风险级别: 低
漏洞原因 : 可以通过 OPTIONS 方法访问 HTTP 服务
漏洞说明: OPTIONS 方法是用于请求获得由 Request-URI 标识的资源在请求/响应的通信过程中可以使用的功能选项。通过这个方法,客户端可以在采取具体资源请求之前,决定对该资源采取何种必要措施,或者了解服务器的性能。OPTIONS方法可能会暴露一些敏感信息,这些信息将帮助攻击者准备更进一步的攻击。
不同的项目,可以通过不同的方法进行修复,在此记录一下几种情况:
说明:项目前置 Nginx,通过 Nginx 配置阻止 OPTIONS 方法的访问。
Nginx 环境
操作系统:CentOS Linux release 7.4.1708 (Core)
Nginx 版本:1.22.0
测试环境
测试操作系统: Windows 11
测试工具 : Postman v9.19.0
直接启动 Nginx ,使用 Postman 访问默认的 80 端口, Postman 截图如下:
说明:
更改 /etc/nginx/conf.d/default.conf 配置文件:
server {listen 80;server_name localhost;#access_log /var/log/nginx/host.access.log main;location / {##### 只增加这里的配置,其他配置为默认 ########## 增加支持 OPTIONS 方法 #####add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';##### 增加 OPTIONS 方法的返回结果 #####if ($request_method = 'OPTIONS') {return 204;}root /usr/share/nginx/html;index index.html index.htm;}#error_page 404 /404.html;# redirect server error pages to the static page /50x.html#error_page 500 502 503 504 /50x.html;location = /50x.html {root /usr/share/nginx/html;}# proxy the PHP scripts to Apache listening on 127.0.0.1:80##location ~ \.php$ {# proxy_pass http://127.0.0.1;#}# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000##location ~ \.php$ {# root html;# fastcgi_pass 127.0.0.1:9000;# fastcgi_index index.php;# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;# include fastcgi_params;#}# deny access to .htaccess files, if Apache's document root# concurs with nginx's one##location ~ /\.ht {# deny all;#}
}
返回结果变为 204
如需要禁止 OPTIONS 方法,则配置文件中的返回结果更改为 403 即可:
if ($request_method ~* OPTIONS) {return 403;
}
修复后,使用 Postman 访问,方法及结果如下:
说明:这个比较容易理解,Nginx 拦截 request_method 是 OPTIONS 的请求,并返回 403。
说明:新版 Tomcat 已经修复了。
修复方法:通过 war 包部署的项目,可以通过更改 Tomcat 的配置阻止 OPTIONS 方法的访问。
操作系统:Windows 11
Tomcat 版本:apache-tomcat-6.0.35-windows-x86
测试工具 : Postman v9.31.0
(PS:文章整理的时间间隔太长了,postman 都升级啦 ~)
修复前,使用 Postman 访问,方法及结果如下:(虽然 response body 是空的,但是状态码是 200)
尝试修复,修改 tomcat 的 conf/web.xml 文件,在标记 前增加以下配置
http method security /* PUT DELETE HEAD OPTIONS TRACE
修复后,使用 Postman 访问,方法及结果如下:(返回 403 Forbidden)
原理(参考博客):(以下内容是老版本的 Tomcat,新版本有待验证)
security-constriant 配置安全相关属性,包含4个可能的子元素,分别是:web-resource-collection、auth-constraint、user-data-constraint和display-name。
说明:
新版 Tomcat 访问会返回 405 Method Not Allowed
访问结果如下
操作系统: Windows 10
JDK 版本:1.8.0_321
SpringBoot 版本: 2.3.7.RELEASE
测试工具 : Postman v9.31.0
初始化 SpringBoot 项目,pom.xml 文件如下
4.0.0 com.example demo 0.0.1-SNAPSHOT demo Demo project for Spring Boot 1.8 UTF-8 UTF-8 2.3.7.RELEASE org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-devtools runtime true org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine org.springframework.boot spring-boot-dependencies ${spring-boot.version} pom import org.apache.maven.plugins maven-compiler-plugin 3.8.1 1.8 1.8 UTF-8 org.springframework.boot spring-boot-maven-plugin 2.3.7.RELEASE com.example.demo.DemoApplication repackage repackage
AppController 定义如下
package com.example.demo.controller;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/api/")
public class AppController {private static final Logger logger = LoggerFactory.getLogger(AppController.class);@RequestMapping("test")
// @PostMapping("test")
// @GetMapping("test")public String test() {return "test";}}
说明:这里有做测试 @RequestMapping @PostMapping @GetMapping 都不会禁用 OPTIONS 请求。
使用 Postman 访问结果如下(说明: OPTIONS 请求允许访问,并在 Headers 中返回了 Allow)
增加过滤器 MyFilter
package com.example.demo.filter;import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpMethod;public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {System.out.println("filter1");HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;// testif (request.getMethod().equals(HttpMethod.OPTIONS.toString())) {response.setStatus(405);return;}String ip = request.getRemoteAddr();String url = request.getRequestURL().toString();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date d = new Date();String date = sdf.format(d);System.out.printf("%s %s 访问了 %s%n", date, ip, url);filterChain.doFilter(request, response);}@Overridepublic void destroy() {}}
注册过滤器
package com.example.demo.config;import com.example.demo.filter.MyFilter;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@SpringBootConfiguration
public class CorsConfiguration implements WebMvcConfigurer {@Beanpublic FilterRegistrationBean registrationBean() {FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new MyFilter());filterRegistrationBean.addUrlPatterns("/*");return filterRegistrationBean;}}
重启服务,使用 Postman 访问结果如下(说明: OPTIONS 请求已被禁用,返回结果 405)
修复方法有很多啦~ 只整理了这3种情况。
说明:有的时候,前后端分离的项目。还不能阻止 OPTIONS 方法的请求,可能会出问题,参考 。有点尴尬,要不这个漏洞不管啦 ??~~!!
上一篇:基于注解方式实现Spring Security忽略拦截
下一篇:U-net