Spring Framework CVE-2020-5408 CORS 配置漏洞

文章目录

  • 0.前言
  • 1.参考文档
  • 2.基础介绍
  • 3.解决方案
    • 3.1. `@CrossOrigin`限制指定来源
    • 3.1. `@ `WebMvcConfigurer` 限制指定来源
    • 3.3. 其他用法
      • 1. 在方法上使用`@CrossOrigin`:
      • 2. 在Controller上使用`@CrossOrigin`:
      • 3. 设置多个源:
      • 4. 设置所有源:
      • 5. 设置允许的HTTP方法:
      • 6. 设置允许的请求头:
      • 7. 设置是否支持凭证:

在这里插入图片描述

0.前言

背景: 一直零散的使用着Spring Boot 的各种组件和特性,从未系统性的学习和总结,本次借着这个机会搞一波。共同学习,一起进步。哈哈

CVE-2020-5408 是一个在Spring Framework中的跨站请求伪造(Cross-Site Request Forgery, CSRF)漏洞。该漏洞主要是由于Spring Framework在处理跨站资源共享(Cross-Origin Resource Sharing, CORS)时的错误配置。

请注意,对于已经在生产环境中运行的应用,修改CORS配置可能会影响到正常的功能。因此,在实施这个修复之前,应该先进行充分的测试。

1.参考文档

官方的Spring文档对@CrossOrigin注解的描述:Spring Framework - Enabling CORS
Spring Framework的CORS配置如果不正确可能导致跨站请求伪造攻击(CSRF)。为了减少这种风险 应该遵循以下最佳实践:

  1. 不要允许所有的源(即避免使用@CrossOrigin(origins = "*"))。相反, 应该明确指定允许的源。我后面会有示例

  2. 限制允许的HTTP方法。例如,你可能只想允许GET和POST请求。这种我们基本都不会限制死,其实价值也不大

  3. 如果可能,避免允许带有凭证的请求。如果你必须允许带凭证的请求,那么确保应用程序在处理这些请求时有足够的安全措施

  4. 在CORS(跨源资源共享)中,一个跨源的请求默认情况下不会发送任何凭据信息,比如HTTP Cookies或HTTP Authentication信息。这样设计的目的是出于安全考虑,防止用户的敏感数据被非法利用。

然而,有时候,我们确实需要在跨源请求中携带这些凭据信息。比如,我们可能需要访问另一个域名下的某个API,而这个API又需要我们提供身份验证信息才能成功访问。在这种情况下,我们可以设置CORS配置,允许请求带有凭证。

在Fetch API或XMLHttpRequest中,我们可以通过设置credentials选项为include来实现这一点。而在服务器端,比如使用Spring框架,我们可以通过在@CrossOrigin注解中设置allowCredentialstrue来允许请求带有凭证。

如果服务器允许请求带有凭证,那么它就不能在处理CORS请求时将Access-Control-Allow-Origin头设置为*,因为浏览器会出于安全考虑而阻止这样的请求。服务器必须明确指定允许的源。

有关CORS和CSRF的参考资料:

  • Spring Framework - CORS

  • MDN Web Docs - Cross-Origin Resource Sharing (CORS)

  • OWASP - Cross-Site Request Forgery (CSRF)

2.基础介绍

简单来说,CORS是一种安全机制,用于控制哪些外部源可以访问到你的应用。在默认情况下,浏览器会阻止跨源(即,不同的域、协议或端口)的 HTTP 请求,以保护用户的隐私。然而,CORS 允许开发者指定哪些外部源可以访问应用,从而打破了这个限制。

在CVE-2020-5408中,Spring Framework的默认CORS配置允许所有的外部源访问应用。这意味着,一个恶意的外部源可以在用户不知情的情况下发起请求,这可能会导致诸如数据泄露、账户劫持等问题。

为了修复这个漏洞,开发者需要显式地配置CORS,指定哪些外部源可以访问应用。例如,可以使用 @CrossOrigin 注解来限制特定的控制器或处理器方法,或者在全局范围内配置 WebMvcConfigurer。这样,只有信任的外部源才能访问应用,从而防止跨站请求伪造攻击。

3.解决方案

3.1. @CrossOrigin限制指定来源

特定的控制器配置CORS。
@CrossOrigin 注解告诉Spring Framework只接受来自 http://trusted-domain.com 的请求。来自其他源的请求将被拒绝。

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class MyController {@CrossOrigin(origins = "http://trusted-domain.com")  // 只允许这个域的请求@GetMapping("/endpoint")public String getEndpoint() {return "Hello, World!";}
}

3.1. @ WebMvcConfigurer` 限制指定来源

如果需要为整个应用配置CORS,可以实现 WebMvcConfigurer 接口,如下所示:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class MyConfiguration implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**")  // 对所有的URL路径生效.allowedOrigins("http://trusted-domain.com")  // 只允许这个域的请求.allowedMethods("GET", "POST", "PUT", "DELETE");  // 允许的HTTP方法}
}

addCorsMappings 方法定义了一个CORS映射,它适用于所有的URL路径,并且只允许来自 http://trusted-domain.comGET, POST, PUT, DELETE 请求。

3.3. 其他用法

@CrossOrigin是一个Spring MVC提供的注解,用于处理CORS(跨源资源共享)。

1. 在方法上使用@CrossOrigin

@RestController
public class MyController {@CrossOrigin(origins = "http://domain2.com")@GetMapping("/endpoint")public String getEndpoint() {return "Hello, World!";}
}

@CrossOrigin注解用在了getEndpoint方法上,只有来自"http://domain2.com"的请求才能访问这个端点。

2. 在Controller上使用@CrossOrigin

@CrossOrigin(origins = "http://domain2.com")
@RestController
public class MyController {@GetMapping("/endpoint")public String getEndpoint() {return "Hello, World!";}
}

@CrossOrigin注解用在了MyController类上,意味着这个类中的所有方法都只允许"http://domain2.com"的请求。

3. 设置多个源:

@CrossOrigin(origins = {"http://domain1.com", "http://domain2.com"})

在这个示例中,允许"http://domain1.com"和"http://domain2.com"的请求。

4. 设置所有源:

@CrossOrigin(origins = "*")

在这个示例中,允许所有的请求,这个引发安全漏洞的配置,在生产环境禁止使用

5. 设置允许的HTTP方法:

@CrossOrigin(origins = "http://domain2.com", methods = {RequestMethod.GET, RequestMethod.POST})

只允许GET和POST请求。

6. 设置允许的请求头:

@CrossOrigin(origins = "http://domain2.com", allowedHeaders = {"header1", "header2"})

在这个示例中,只允许包含"header1"和"header2"的请求。

7. 设置是否支持凭证:

允许请求带有凭证。

@CrossOrigin(origins = "http://domain2.com", allowCredentials = "true")

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【问题总结+备忘录】上传一个shp文件能够读取其中的空间矢量字段,代码+采坑总结

需求描述 要求上传一个shp文件能够读取其中的空间矢量字段。 简单分析 SHP上传格式应该有两种(zip格式和.shp的格式文件内部可能存在多个空间矢量,结果以列表形式返回文件不大,使用MultipartFile上传上传即可结合geo-tools读取空间字段&am…

上门服务系统|上门服务小程序如何提升生活质量?

上门服务其实就是本地生活服务的升级,上门服务包含很多行业可以做的。例如:厨师上门、上门家电维修、跑腿等等。如今各类本地化生活服务越来越受大家的喜爱。基于此市场愿景,我们来谈谈上门服务系统功能。 一、上门服务系统功能 1、预约服务…

springboot整合rabbitmq死信队列

springboot整合rabbitmq死信队列 什么是死信 说道死信,可能大部分观众大姥爷会有懵逼的想法,什么是死信?死信队列,俗称DLX,翻译过来的名称为Dead Letter Exchange 死信交换机。当消息限定时间内未被消费,…

算法通关村十三关 | 数组字符串加法专题

1. 数组实现整数加法 题目:LeetCode66,66. 加一 - 力扣(LeetCode) 思路 我们只需要从头到尾依次运算,用常量标记是否进位,需要考虑的特殊情况是digits [9,9,9]的时候进位,我们组要创建长度加1…

CNN 02(CNN原理)

一、卷积神经网络(CNN)原理 1.1 卷积神经网络的组成 定义 卷积神经网络由一个或多个卷积层、池化层以及全连接层等组成。与其他深度学习结构相比,卷积神经网络在图像等方面能够给出更好的结果。这一模型也可以使用反向传播算法进行训练。相比较其他浅层或深度神经…

二、数学建模之整数规划篇

1.定义 2.例题 3.使用软件及解题 一、定义 1.整数规划(Integer Programming,简称IP):是一种数学优化问题,它是线性规划(Linear Programming,简称LP)的一个扩展形式。在线性规划中&…

格子游戏——并查集

Alice和Bob玩了一个古老的游戏:首先画一个 nn 的点阵(下图 n3 )。 接着,他们两个轮流在相邻的点之间画上红边和蓝边: 直到围成一个封闭的圈(面积不必为 1)为止,“封圈”的那个人就是…

53 个 CSS 特效 2

53 个 CSS 特效 2 这里是第 17 到 32 个,跟上一部分比起来多了两个稍微大一点的首页布局,上篇:53 个 CSS 特效 1,依旧,预览地址在 http://www.goldenaarcher.com/html-css-js-proj/,git 地址: …

Qt --- 自定义提示框 类似QMessagebox

QMessageBox::information(NULL, QString("title"), QString("I am information")); 以下是自定义提示框的代码,有图有真相!提示框大部分都采用模态的形式,关于模态也不再多提!所以父类为QDialog,…

IDEA启动两个Tomcat服务的方式 使用nginx进行反向代理 JMeter测试分布式情况下synchronized锁失效

目录 引出IDEA启动Tomcat两个端口的方式1.编辑配置2.添加新的端口-Dserver.port80833.service里面管理4.启动后进行测试 使用nginx进行反向代理反向代理多个端口运行日志查看启动关闭重启 分布式情况下synchronized失效synchronized锁代码启动tomcat两个端口nginx反向代理JMete…

Python3 字典

Python3 字典 字典是另一种可变容器模型,且可存储任意类型对象。 字典的每个键值 key>value 对用冒号 : 分割,每个对之间用逗号(,)分割,整个字典包括在花括号 {} 中 ,格式如下所示: d {key1 : value1, key2 : value2, key3…

列式存储引擎-内核机制-Parquet格式

列式存储引擎-内核机制-Parquet格式 Parquet是一种开源的列式存储结构,广泛应用于大数据领域。 1、数据模型和schema Parquet继承了Protocol Buffer的数据模型。每个记录由一个或多个字段组成。每个字段可以是atomic字段或者group字段。Group字段包含嵌套的字段&…