OPTIONS 漏洞修复

news2025/4/8 12:12:29

文章目录

  • 前言:OPTIONS 漏洞说明
  • Nginx 修复方法
    • 环境说明
    • 修复测试
  • Tomcat 修复方法
    • 环境说明
    • 修复测试
    • Tomcat 版本:8.5.3 测试
  • SpringBoot 项目修复方法
    • 环境说明
    • 修复测试
  • 总结


前言:OPTIONS 漏洞说明

漏洞名称 : OPTIONS method is enabled

风险级别: 低

漏洞原因 : 可以通过 OPTIONS 方法访问 HTTP 服务

漏洞说明: OPTIONS 方法是用于请求获得由 Request-URI 标识的资源在请求/响应的通信过程中可以使用的功能选项。通过这个方法,客户端可以在采取具体资源请求之前,决定对该资源采取何种必要措施,或者了解服务器的性能。OPTIONS方法可能会暴露一些敏感信息,这些信息将帮助攻击者准备更进一步的攻击。

不同的项目,可以通过不同的方法进行修复,在此记录一下几种情况:

  1. 更改 Nginx 的配置;
  2. 更改 Tomcat 参数;
  3. SpringBoot 项目增加过滤器。

Nginx 修复方法

说明:项目前置 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 截图如下:

在这里插入图片描述

说明:

  • 默认没有开启 options 方法。
  • 如果做转发测试,还要再搭建其他服务,只想测试一下而已。动一下手脚,改一下吧!

更改 /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 修复方法

说明:新版 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。

  1. web-resource-collection 此元素确定要保护的资源,所有 security-constraint 元素都必须包含至少一个此项。此元素下面有一个给出任意标识名称的 <web-resource-name> 、一个确定要保护的 URL 的 url-pattern 元素、一个指出此保护所适用的 HTTP 命令(缺省为所有方法)的 http-method 元素和一个提供资料的可选 description 元素组成。如上例中,当以 OPTIONGS 方法访问时将被限制,如果把 <http-method>OPTIONS</http-method> 这行注释掉就不会报错了
  2. auth-constraint 元素指出哪些用户应该具有受保护资源的访问权。此元素应该包含一个或多个标识具有访问权限的用户 role-name 元素,以及可选的 description 元素。如果 security-constraint 中没有 auth-constraint 子元素,任何身份的用户都可以访问相应的资源,也就是说 security-constraint 这时实际上不起作用。此元素需要和 <login-config> 配合使用,<login-config> 要紧跟 security-constraint 后面
  3. user-data-constraint 此可选元素指出在访问相关资源时使用的传输层保护

说明:

  • security-constraint只对外部访问有作用,对内部跳转是不起作用的。
  • web.xml 中 <security-constraint> 的子元素 <http-method> 是可选的,如果没有 <http-method> 元素,这表示将禁止所有 HTTP 方法访问相应的资源。子元素 <auth-constraint> 需要和 <login-config> 相配合使用,但可以被单独使用。如果没有 <auth-constraint> 子元素,这表明任何身份的用户都可以访问相应的资源。也就是说,如果 <security-constraint> 中没有 <auth-constraint> 子元素的话,配置实际上是不起中用的。如果加入了 <auth-constraint> 子元素,但是其内容为空,这表示所有身份的用户都被禁止访问相应的资源。

Tomcat 版本:8.5.3 测试

新版 Tomcat 访问会返回 405 Method Not Allowed
访问结果如下
在这里插入图片描述

SpringBoot 项目修复方法

环境说明

操作系统: 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 方法的请求,可能会出问题,参考 。有点尴尬,要不这个漏洞不管啦 ??~~!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/109636.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker+Jenkins+Gitee+Maven构建后台jar包后配置SSH传送到服务器并执行指定命令

场景 DockerJenkinsGiteeMaven项目配置jdk、maven、gitee等拉取代码并自动构建以及遇到的那些坑&#xff1a; DockerJenkinsGiteeMaven项目配置jdk、maven、gitee等拉取代码并自动构建以及遇到的那些坑_霸道流氓气质的博客-CSDN博客 在上面将后台jar包构建成功之后&#xff…

【SpringMVC】SpringMVC的入门

1.SpringMVC的入门案例 1.1 项目目录 1.2 配置核心控制器和编码过滤器(web.xml) <?xml version"1.0" encoding"UTF-8"?> <web-app><display-name>Archetype Created Web Application</display-name><!--配置spring mvc的核…

20221223英语学习

今日托福词汇 review n.复习; 回顾, 检讨; 检阅; 评论; 详检, 审核; 回放功能 tentative adj.试验性的; 不确定的; 暂时的; 犹豫的, 踌躇不决的 synonym n.同义词 confine v.限制&#xff1b;监禁 parking n.机动车停放&#xff1b;停车场 sculpture n.雕像&#xff0c;雕…

高通 OpenXR SDK 使用指南(2)

高通 OpenXR SDK 使用指南&#xff08;2&#xff09;1.5 OpenXR 生命周期1.5 OpenXR 生命周期 下图是 OpenXR 框架生命周期的流转过程。 此图中描述了以下过程&#xff1a; 应用程序首先使用 xrEnumerateApiLayerProperties 查询 API 层和扩展属性。 API层可以是以下类型&a…

Zookeeper 4 Zookeeper JavaAPI 操作 4.6 Curator API 常用操作【删除节点】

Zookeeper 【黑马程序员Zookeeper视频教程&#xff0c;快速入门zookeeper技术】 文章目录Zookeeper4 Zookeeper JavaAPI 操作4.6 Curator API 常用操作4.6.1 删除节点4 Zookeeper JavaAPI 操作 4.6 Curator API 常用操作 4.6.1 删除节点 直接开干 /*** 删除节点* 1. 删除单…

【Java基础知识复盘】ArrayList、LinkedList篇——持续更新中

本人知识复盘系列的博客并非全部原创&#xff0c;大部分摘自网络&#xff0c;只是为了记录在自己的博客方便查阅&#xff0c;往后也会陆续在本篇博客更新本人查阅到的新的知识点&#xff0c;望悉知&#xff01; ArrayList 概述 ArrayList 类是一个可以动态修改的数组&#xf…

C++【图】

文章目录一、什么是图二、图的存储结构1.邻接矩阵2.邻接表三、邻接表的代码实现四、邻接矩阵的代码实现五、图的相关属性六、图的遍历1.深度优先遍历2.广度优先遍历练习七、最小生成树1.Kruskal算法&#xff08;克鲁斯卡尔算法&#xff09;2.prim算法八、最短路径1.Dijkstra算法…

Zookeeper 4 Zookeeper JavaAPI 操作 4.8 分布式锁

Zookeeper 【黑马程序员Zookeeper视频教程&#xff0c;快速入门zookeeper技术】 文章目录Zookeeper4 Zookeeper JavaAPI 操作4.8 分布式锁4.8.1 分布式锁4.8.2 Zookeeper 分布式锁原理4 Zookeeper JavaAPI 操作 4.8 分布式锁 4.8.1 分布式锁 在我们进行单机应用开发&#x…

[附源码]计算机毕业设计Python失物招领微信小程序论文(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

微信公众号迁移,需要做些什么

❤️ 个人主页&#xff1a;水滴技术 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; &#x1f338; 订阅专栏&#xff1a;微信公众平台 文章目录一、开通开发者二、设置IP白名单三、自定义菜单四、认证五、网页授权域名六、模板消息七、转换…

芯片漫游指南(4) -- UVM序列

1 新手上路 1.1 概述 在UVM世界&#xff0c;利用其核心特性&#xff0c;在创建了组件和顶层环境&#xff0c;并且完成组件之间的TLM端口连接之后&#xff0c;接下来就可以使得整个环境开始运转了。 在经过一番时间&#xff0c;掌握了组件之间的TLM通信方式&#xff0c;开辟了…

十四、Docker 微服务实战

1、创建SpringBoot项目 hello_docker 1.1、项目结构 1.2、项目所有代码 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-inst…

Shiro与SpringBoot整合

Shiro与SpringBoot整合 这里前端页面 采用thymeleaf进行渲染 1、导入基本的依赖坐标 <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-web-starter</artifactId><version>1.9.0</version> </d…

【云原生 | 48】Etcd集群管理

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…

HTML知识1

1. title标签&#xff1a;声明网页的标题 2.meta标签&#xff1a;描述应该网页的属性 3.style标签&#xff1a;内嵌css样式 4.script标签&#xff1a;用来引入javascript程序 5.html常用特殊字符 6.注释&#xff1a;<&#xff01;--此处是注释--> 二.标签 属性…

Android实现一维二维码扫描生成功能(一)-zxing导入现有项目

前言 目前二维码扫描功能很流行也非常成熟了&#xff0c;而zxing项目也是目前可以说是最流行的二维码扫描方面的开源项目了&#xff0c;很多大神都对zxing进行了封装&#xff0c;github上也有很多好用的二维码开源库&#xff0c;但是我更喜欢原版的zxing开源库&#xff0c;而原…

Struts2框架简单入门

Struts2框架简单入门1、前言2、Struts2简介2.1、Struts2介绍2.2、Struts2优缺点2.2.1、优点2.2.2、缺点2.2.3、Struts2获取3、入门案例3.1、pom依赖3.2、web.xml配置3.3、准备页面3.4、编写Action控制器3.5、编写核心配置文件struts.xml3.6、部署测试3.6、注意点3.7、小结1、前…

Android -- 每日一问:如何实现自定义View?

经典回答 回忆一下&#xff0c;你去面试时常被问到的自定义 View 方面的问题是那些。有没有&#xff1a; invalidate 和 postInvalidate 方法的区别&#xff1f;自定义 View 的绘制流程&#xff1f;View 的 Touch 事件分发流程&#xff1f; 因为在实际的工作中并不是每个人都…

【Go实现】实践GoF的23种设计模式:命令模式

上一篇&#xff1a;【Go实现】实践GoF的23种设计模式&#xff1a;代理模式 简单的分布式应用系统&#xff08;示例代码工程&#xff09;&#xff1a;https://github.com/ruanrunxue/Practice-Design-Pattern–Go-Implementation 简介 现在的软件系统往往是分层设计。在业务层执…

设计vue3组件

在程序设计过程中&#xff0c;我们经常会遇到很多地方用到相同结构内容的情况&#xff0c;这时&#xff0c;我们想复用一部分代码&#xff0c;这时可以将可复用的UI部分以组件的形态封装&#xff0c;形成一定的组件调用关系。 组件化最简单的就是把一段代码提出来单独写进一个…