文章目录
漏洞名称 : 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 文件,在标记 前增加以下配置
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- add -->
<security-constraint>
<web-resource-collection>
<web-resource-name>http method security</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>HEAD</http-method>
<!-- 只禁用 OPTIONS 方法,只增加这个就好啦 -->
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
</web-resource-collection>
<auth-constraint/>
</security-constraint>
<!-- 这里之前增加配置 -->
</webapp>
修复后,使用 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 文件如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>com.example.demo.DemoApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
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 {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
System.out.println("filter1");
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// test
if (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);
}
@Override
public 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 {
@Bean
public FilterRegistrationBean registrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new MyFilter());
filterRegistrationBean.addUrlPatterns("/*");
return filterRegistrationBean;
}
}
重启服务,使用 Postman 访问结果如下(说明: OPTIONS 请求已被禁用,返回结果 405)

修复方法有很多啦~ 只整理了这3种情况。
说明:有的时候,前后端分离的项目。还不能阻止 OPTIONS 方法的请求,可能会出问题,参考 。有点尴尬,要不这个漏洞不管啦 ??~~!!
我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request
目录1.漏洞简介2、AJP13协议介绍Tomcat主要有两大功能:3.Tomcat远程文件包含漏洞分析4.漏洞复现 5、漏洞分析6.RCE实现的原理1.漏洞简介2020年2月20日,公开CNVD的漏洞公告中发现ApacheTomcat文件包含漏洞(CVE-2020-1938)。ApacheTomcat是Apache开源组织开发的用于处理HTTP服务的项目。ApacheTomcat服务器中被发现存在文件包含漏洞,攻击者可利用该漏洞读取或包含Tomcat上所有webapp目录下的任意文件。该漏洞是一个单独的文件包含漏洞,依赖于Tomcat的AJP(定向包协议)。AJP自身存在一定缺陷,导致存在可控
执行rvmlist后,我得到以下输出:rvmrubiesgems[missingbin/ruby]=*ruby-2.0.0-p645[x86_64]ruby-2.1.6[x86_64]ruby-2.2.1[x86_64]gems[missingbin/ruby]是什么意思?gems是某种系统gemset吗?它不是我创建的,我不知道我是否可以或应该删除它。 最佳答案 在我跑完之后:rvmfix-permissions然后我能够卸载具有[缺少bin/ruby]的版本。 关于ruby-如何修复
尝试从我的AngularJS端将数据发布到Rails服务器时出现问题。服务器错误:ActionController::RoutingError(Noroutematches[OPTIONS]"/users"):actionpack(4.1.9)lib/action_dispatch/middleware/debug_exceptions.rb:21:in`call'actionpack(4.1.9)lib/action_dispatch/middleware/show_exceptions.rb:30:in`call'railties(4.1.9)lib/rails/rack/logg
什么是0day漏洞?0day漏洞,是指已经被发现,但是还未被公开,同时官方还没有相关补丁的漏洞;通俗的讲,就是除了黑客,没人知道他的存在,其往往具有很大的突发性、破坏性、致命性。0day漏洞之所以称为0day,正是因为其补丁永远晚于攻击。所以攻击者利用0day漏洞攻击的成功率极高,往往可以达到目的并全身而退,而防守方却一无所知,只有在漏洞公布之后,才后知后觉,却为时已晚。“后知后觉、反应迟钝”就是当前安全防护面对0day攻击的真实写照!为了方便大家理解,中科三方为大家梳理当前安全防护模式下,一个漏洞从发现到解决的三个时间节点:T0:此时漏洞即0day漏洞,是已经被发现,还未被公开,官方还没有相
我有一个依赖于另一个gem的gem(在RubyGems上可用)。那个依赖的gem有一个我最近修复的错误。不幸的是,那个依赖的gem几乎已经死了;它已经很多年没有更新了,而且所有者不再在GitHub上活跃,根本,更不用说提交这个gem了,所以我不希望我的补丁会被接受——肯定不会很快。鉴于此,处理此依赖gem的补丁版本的最佳方法是什么?我是否将它fork并上传一个新的gem(使用新名称)到RubyGems,并依赖它?我是否以某种方式将我的固定版本与我自己的gem打包在一起? 最佳答案 首先,检查有问题的gem的许可证(以及您的代码的许可
Facebook刚刚重新推出了具有自动语法修复功能的评论。Whatdoesthegrammarfilterdo?Addspunctuation(e.g.periodsattheendofsentences)TrimsextrawhitespaceAutocaseswords(e.g.capitalizethefirstwordofasentence)Expandsslangwords(e.g.plzbecomesplease)Addsaspaceafterpunctuation(e.g.Hi,CatwouldbecomeHi,Cat)Fixcommongrammarmistakes(e
我在尝试安装ruby和rails时遇到了很多问题。在清除以前安装的版本之后,我已经尝试过没有和现在。尝试运行“geminstallrdiscount--platform=ruby”时出现以下错误:C:\Windows\system32>geminstallrdiscount--platform=rubyTemporarilyenhancingPATHtoincludeDevKit...Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingrdiscount:ERROR:Failedtobuildgem
我有以下文件结构:执行.rb图书馆我的类(class).rb在execute.rb我有下面的代码:#!/usr/bin/rubyrequire'lib/my_class'my_object=MyClass.newmy_object.some_method这是my_class.rb的代码:classMyClassdefsome_methodputs'OK'endend所以,我尝试运行execute.rb:rubyexecute.rb但是我收到这个错误:/home/vagrant/.rvm/rubies/ruby-2.0.0-p195/lib/ruby/site_ruby/2.0.0/ru