Spring官方提供【CSRF攻击】解决方案

news2024/11/13 8:55:38

步入正文

Cookie

cookie是我们常见用来保存用户态信息,cookie跟随我们的请求自动携带。在同一域名下的请求,cookie总是自动携带。

用户态: 当前登入者的用户信息

以上的特性会导致一个潜在漏洞-CSRF

CSRF

CSRF一般指跨站请求伪造。 跨站请求伪造(英语:Cross-site request forgery),下图举一个例子:在这里插入图片描述
危险漏洞出现在步骤四:此时网站B请求了网站A,又因为cookie的特性(会将一二步骤使用的Cookie)导致请求成功,此时的转账是成功的。
就此出现了CSRF( 跨站请求伪造)漏洞。

解决方案

Spring 提供了两种机制来防止 CSRF 攻击:

  1. 同步器令牌模式
  2. 在会话 Cookie 上指定同一网站属性

这两种保护都要求安全方法是幂等的。

1.同步器令牌模式

防范 CSRF 攻击的主要和最全面的方法是使用同步器令牌模式。 此解决方案是为了确保除了我们的会话 cookie 之外,每个 HTTP 请求还需要在 HTTP 请求中存在一个称为 CSRF 令牌的安全随机生成值。

提交 HTTP 请求时,服务器必须查找预期的 CSRF 令牌,并将其与 HTTP 请求中的实际 CSRF 令牌进行比较。 如果值不匹配,则应拒绝 HTTP 请求。

这项工作的关键是实际的CSRF令牌应该在HTTP请求的一部分中,浏览器不会自动包含该部分。 例如,在 HTTP 参数或 HTTP请求头中要求实际的 CSRF 令牌将防止 CSRF 攻击。 在 cookie 中要求实际的 CSRF 令牌是行不通的,因为浏览器会自动将 cookie 包含在 HTTP 请求中。

我们可以放宽期望,为每个更新应用程序状态的 HTTP (PUT,POST,DELETE)请求仅要求实际的 CSRF 令牌。 为此,我们的应用程序必须确保安全的 HTTP 方法是幂等的。 这提高了可用性,因为我们希望允许从外部网站链接到我们的网站。 此外,我们不希望在 HTTP GET 中包含随机令牌,因为这可能会导致令牌泄露。

考虑一下使用同步器令牌模式时我们的示例将如何变化。 假设实际的 CSRF 令牌需要位于名为 的 HTTP 参数中。 我们应用程序的转移表单如下所示:

2. 同网站属性

防止CSRF攻击的一种新兴方法是在cookie上指定SameSite属性。 服务器可以在设置 Cookie 时指定属性,以指示来自外部站点时不应发送 Cookie

具有该属性的 HTTP 响应标头的示例可能如下所示:

Set-Cookie: JSESSIONID=randomid; Domain=bank.example.com; Secure; HttpOnly; SameSite=Lax

该属性的有效值为:SameSite

  1. Strict:指定后,来自同一站点的任何请求都包含 cookie。 否则,Cookie 不会包含在 HTTP 请求中。
  2. Lax:指定后,当来自同一站点或请求来自顶级导航且方法幂等时,将发送 Cookie。 否则,Cookie 不会包含在 HTTP 请求中。

在我们的会话 Cookie 上设置该属性后,浏览器会继续发送来自银行网站的请求的 Cookie。 但是,浏览器不再发送带有来自邪恶网站的传输请求的cookie。 由于会话不再存在于来自恶意网站的传输请求中,因此应用程序受到保护,免受CSRF攻击。

另一个明显的考虑因素是,为了使属性保护用户,浏览器必须支持该属性。 大多数现代浏览器都支持 SameSite 属性。 但是,仍在使用的旧版浏览器可能不会。

出于这个原因,我们通常建议将该属性用作深度防御,而不是针对 CSRF 攻击的唯一保护

何时使用 CSRF 保护

何时应使用 CSRF 保护? 我们的建议是对普通用户可以通过浏览器处理的任何请求使用 CSRF 保护。 如果要创建仅由非浏览器客户端使用的服务(Frame等嵌套),则可能需要禁用 CSRF 保护。

CSRF 保护和 JSON

一个常见的问题是“我需要保护JavaScript发出的JSON请求吗? 简短的回答是:视情况而定。 但是,您必须非常小心,因为存在会影响 JSON 请求的 CSRF 漏洞。 例如,恶意用户可以使用以下形式使用 JSON 创建 CSRF:

<form action="https://bank.example.com/transfer" method="post" enctype="text/plain">
	<input name='{"amount":100,"routingNumber":"evilsRoutingNumber","account":"evilsAccountNumber", "ignore_me":"' value='test"}' type='hidden'>
	<input type="submit"
		value="Win Money!"/>
</form>

这将生成以下 JSON 结构

{ "amount": 100,
"routingNumber": "evilsRoutingNumber",
"account": "evilsAccountNumber",
"ignore_me": "=test"
}

如果应用程序未验证header,则会暴露在此攻击中。 根据设置的不同,验证内容类型的Spring MVC应用程序仍可以通过将URL后缀更新为以 结尾来利用,如下所示:Content-Type.json

<form action="https://bank.example.com/transfer.json" method="post" enctype="text/plain">
	<input name='{"amount":100,"routingNumber":"evilsRoutingNumber","account":"evilsAccountNumber", "ignore_me":"' value='test"}' type='hidden'>
	<input type="submit"
		value="Win Money!"/>
</form> 

CSRF 和无状态浏览器应用程序

如果我的应用程序是无状态的怎么办? 这并不一定意味着您受到保护。 事实上,如果用户不需要在 Web 浏览器中对给定的请求执行任何操作,他们可能仍然容易受到 CSRF 攻击。

例如,考虑一个应用程序,它使用自定义 cookie,其中包含用于身份验证的所有状态(而不是 JSESSIONID)。 当进行 CSRF 攻击时,自定义 cookie 与请求一起发送的方式与前面示例中发送 JSESSIONID cookie 的方式相同。 此应用程序容易受到 CSRF 攻击。

使用基本身份验证的应用程序也容易受到 CSRF 攻击。 该应用程序容易受到攻击,因为浏览器会自动在任何请求中包含用户名和密码,其方式与上一个示例中发送 JSESSIONID cookie 的方式相同。

CSRF 注意事项

在实施针对 CSRF 攻击的保护时,需要考虑一些特殊注意事项。

登录

为了防止伪造登录请求,应保护登录 HTTP 请求免受 CSRF 攻击。 防止伪造登录请求是必要的,以便恶意用户无法读取受害者的敏感信息。 攻击的执行方式如下:

伪造登录请求:攻击者可能会伪造请求,使用攻击者的凭据将受害者登录到目标网站;这称为登录 CSRF。登录CSRF使各种新颖的攻击成为可能;例如,攻击者稍后可以使用其合法凭据登录站点,并查看私人信息,例如已保存在帐户中的活动历史记录。这种攻击已经针对谷歌[12]和雅虎进行了演示。[注13]

  1. 恶意用户使用恶意用户的凭据执行 CSRF 登录。 受害者现在被验证为恶意用户。
  2. 然后,恶意用户诱骗受害者访问受感染的网站并输入敏感信息。
  3. 该信息与恶意用户的帐户相关联,因此恶意用户可以使用自己的凭据登录并查看受害者的敏感信息。

确保登录 HTTP 请求免受 CSRF 攻击的一个可能的复杂性是,用户可能会遇到会话超时,从而导致请求被拒绝。 会话超时对于不希望需要会话才能登录的用户来说令人惊讶。 有关更多信息,请参阅 CSRF 和会话超时。

注销

为了防止伪造注销请求,应保护注销 HTTP 请求免受 CSRF 攻击。 防止伪造注销请求是必要的,以便恶意用户无法读取受害者的敏感信息。 有关攻击的详细信息,请参阅此博客文章。

确保注销 HTTP 请求免受 CSRF 攻击的一个可能的复杂性是,用户可能会遇到导致请求被拒绝的会话超时。 会话超时对于不希望有会话注销的用户来说令人惊讶。 有关更多信息,请参阅 CSRF 和会话超时。

CSRF 和会话超时

通常,预期的CSRF令牌存储在会话中。 这意味着,一旦会话过期,服务器就找不到预期的 CSRF 令牌并拒绝 HTTP 请求。 有许多选项(每个选项都有权衡)来解决超时问题:

  1. 缓解超时的最佳方法是使用 JavaScript 在表单提交时请求 CSRF 令牌。 然后,使用CSRF令牌更新表单并提交。
  2. 另一种选择是使用一些 JavaScript,让用户知道他们的会话即将过期。 用户可以单击按钮以继续并刷新会话。
  3. 最后,预期的CSRF令牌可以存储在cookie中。 这让预期的 CSRF 令牌比会话更长久。

有人可能会问,为什么预期的CSRF令牌默认情况下不存储在cookie中。 这是因为存在已知的漏洞,其中标头(例如,指定 cookie)可由另一个域设置。 这与Ruby on Rails在标头X-Request-With存在时不再跳过CSRF检查的原因相同。 有关如何执行漏洞利用的详细信息,请参阅此 webappsec.org 线程。 另一个缺点是,通过删除状态(即超时),您将失去在令牌遭到入侵时强制使令牌无效的能力。

分段(文件上传)

保护分段请求(文件上传)免受 CSRF 攻击会导致先有鸡还是先有蛋的问题。 为了防止CSRF攻击的发生,必须读取HTTP请求的正文以获取实际的CSRF令牌。 但是,读取正文意味着文件已上传,这意味着外部站点可以上传文件。

对多部分/表单数据使用 CSRF 保护有两种选择:

  1. 将CSRF令牌放入正文
  2. 将 CSRF 令牌放在 URL 中

每个选项都有其权衡取舍。

在将 Spring Security 的 CSRF 保护与分段文件上传集成之前,您应该首先确保可以在没有 CSRF 保护的情况下进行上传。 有关在 Spring 中使用多部分表单的更多信息,请参见 1.1.11。Spring 参考的多部分解析器部分和 MultipartFilter Javadoc。

将CSRF令牌放入正文

第一个选项是在请求正文中包含实际的 CSRF 令牌。 通过将 CSRF 令牌放在正文中,可以在执行授权之前读取正文。 这意味着任何人都可以在您的服务器上放置临时文件。 但是,只有授权用户才能提交由您的应用程序处理的文件。 通常,这是推荐的方法,因为临时文件上载对大多数服务器的影响可以忽略不计。

在 URL 中包含 CSRF 令牌

如果不允许未经授权的用户上传临时文件,另一种方法是在表单的操作属性中包含预期的 CSRF 令牌作为查询参数。 此方法的缺点是查询参数可能会泄漏。 更一般地说,最佳做法是将敏感数据放在正文或标头中,以确保它不会泄露。 您可以在 RFC 2616 第 15.1.3 节 URI 中的敏感信息编码中找到其他信息。

隐藏的HttpMethodFilter
某些应用程序可以使用表单参数来重写 HTTP 方法。 例如,以下表单可以将 HTTP 方法视为 而不是 .deletepost

CSRF 隐藏的 HTTP 方法表单

<form action="/process"
	method="post">
	<!-- ... -->
	<input type="hidden"
		name="_method"
		value="delete"/>
</form>

重写 HTTP 方法发生在筛选器中。 该过滤器必须放在 Spring Security 的支持之前。 请注意,覆盖只发生在 上,因此这实际上不太可能导致任何实际问题。 但是,最佳做法仍然是确保将其放置在 Spring 安全性的过滤器之前。post

本文

主要来源
https://docs.spring.io/spring-security/reference/features/exploits/csrf.html#csrf-when-stateless
https://docs.spring.io/spring-security/reference/features/exploits/csrf.html#csrf-when-stateless
https://docs.spring.io/spring-security/reference/features/exploits/csrf.html#csrf-when-stateless

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

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

相关文章

长安链合约标准协议启动建设,邀请社区用户评审

智能合约是区块链摆脱第三方&#xff0c;实现验证、执行业务逻辑的“看不见的手”。随着联盟链产业落地进入快车道&#xff0c;需要面对的应用场景更加多样&#xff0c;智能合约标准协议作为推动联盟链应用生态繁荣的重要一环也需要加速推进发展。 区块链技术正在发展中规范。…

PHP 连接 MySQL

PHP 5 及以上版本建议使用以下方式连接 MySQL : MySQLi extension ("i" 意为 improved)PDO (PHP Data Objects) 在 PHP 早期版本中我们使用 MySQL 扩展。但该扩展在 2012 年开始不建议使用。 我是该用 MySQLi &#xff0c;还是 PDO? 如果你需要一个简短的回答&…

C语言 栈的应用 计算简单的中缀表达式

代码简介&#xff1a;下面的代码实现了计算简单的中缀表达式&#xff1a;只可以处理一位正整数的四则运算及括号。是栈的简单应用&#xff0c;要实现中缀表达式运算需要用两个栈&#xff0c;一个存储数字的栈和一个存储运算符的栈&#xff0c;因为懒得写两遍不同的栈上的操作&a…

增益自适应PI控制器+死区过滤器(Smart PLC向导PID编程应用)

增益自适应和死区过滤器如果不和S7-200 SMART PLC PID向导组合实现,大家可以自行编写优化的PID指令。算法起始非常简单,具体实现过程大家可以参看下面的文章链接, 三菱增量式PID+死区过滤器 三菱PLC增量式PID算法FB(带死区设置和外部复位控制)_RXXW_Dor的博客-CSDN博客关于…

【论文简述】High-Resolution Optical Flow from 1D Attention and Correlation(ICCV 2021)

一、论文简述 1. 第一作者&#xff1a;Haofei Xu 2. 发表年份&#xff1a;2021 3. 发表期刊&#xff1a;ICCV 4. 关键词&#xff1a;光流、代价体、自注意力、高分辨率、GRU 5. 探索动机&#xff1a;小分辨率对于网络性能有影响&#xff0c;并且现实场景中大多为高分辨率的…

Minecraft 1.19.2 Fabric模组开发 04.动画效果方块

我们本次尝试在1.19 Fabric中制作一个具有动画效果的方块 效果演示效果演示效果演示 首先&#xff0c;请确保你的开发包中引入了geckolib依赖&#xff0c;相关教程请参考:Minecraft 1.19.2 Fabric模组开发 03.动画生物实体 1.首先我们要使用geckolib制作一个物品和对应的动画…

eCharts工具类

ECharts是一款基于JavaScript的数据可视化图表库&#xff0c;提供直观&#xff0c;生动&#xff0c;可交互&#xff0c;可个性化定制的数据可视化图表。ECharts最初由百度团队开源&#xff0c;并于2018年初捐赠给Apache基金会&#xff0c;成为ASF孵化级项目。 ECharts官方地址…

【数据结构与算法】顺序表的原理及实现

1.什么是顺序表 顺序表是用一段物理地址连续的存储单元进行存储元素的线性结构&#xff0c;通常是以数组进行存储。通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系。 2.顺序表的实现 判断顺序表是否为空表public boolean isEmpty()判断顺序表是否满publi…

excel功能小技巧:自动求和的注意事项

在EXCEL里有个非常方便的按钮&#xff0c;叫做自动求和。不需要输入公式&#xff0c;直接一点&#xff0c;即可得出求和结果。由于它操作上的便利&#xff0c;所以深受小白喜爱。不过看着简单的自动求和按钮&#xff0c;实际上却藏着不少暗坑&#xff0c;稍不留神&#xff0c;可…

juc系列(2)--线程的使用及原理

目录线程创建线程ThreadRunnableCallable线程方法APIrun startsleep yieldjoininterrupt打断线程打断 park终止模式daemon不推荐线程原理运行机制线程调度未来优化线程状态查看线程线程 创建线程 Thread Thread 创建线程方式&#xff1a;创建线程类&#xff0c;匿名内部类方…

R-P-Faster R-CNN day65 读论文:高分辨率遥感影像综合地理空间目标检测框架

An Efficient and Robust Integrated Geospatial Object Detection Framework for High Spatial Resolution Remote Sensing Imagery 1. Introduction3. Overview of the Proposed R-P-Faster R-CNN Framework3.1. 有效集成区域建议网络与目标检测Faster R-CNN框架3.1.2. RPN与…

java反射在spring ioc和aop中的应用

java反射在spring ioc和aop中的应用 反射&#xff1a; 1.反射是什么&#xff1f; 程序运行时&#xff0c;通过类名能够获得类的属性和方法。使用方式如下 Class clazz Class.ForName(“Student”)Class clazz Student.class;Class clazz student.getClass(); 获取到claz…

java JUC 中 Object里wait()、notify() 实现原理及实战讲解

1.Object中的wait()实现原理 在进行wait()之前&#xff0c;就代表着需要争夺Synchorized&#xff0c;而Synchronized代码块通过javap生成的字节码中包含monitorenter和monitorexit两个指令。 当在进加锁的时候会执行monitorenter指令&#xff0c;执行该指令可以获取对象的mon…

前端与HTML

本节课程围绕“前端要解决的基本问题”及“什么是 HTML ”两个基本问题展开&#xff0c;了解 HTML 高效的编写原则。 什么是前端 使用web技术栈解决多端的人机交互问题 技术栈 html&#xff08;内容&#xff09; css &#xff08;样式&#xff09;javascript &#xff08;行…

linux部署KubeSphere和k8s集群

上一篇文章讲述了在单个节点上安装 KubeSphere和k8s&#xff0c;这节主要讲解k8s多节点集群部署 准备环境&#xff1a;Alibaba Cloud Linux系统3台机器第一步&#xff1a;设置主机名称hostname--(3台机器都设置) hostnamectl set-hostname master hostnamectl set-hostname nod…

智云通CRM:为什么你总是在请客,但业绩却上不来?

王总是一位企业老板&#xff0c;社会资源比较好&#xff0c;在过去的一年里&#xff0c;他新代理的一个保健品的项目&#xff0c;需要销售产品和招募合伙人。他想利用自己的人脉资源做销售&#xff0c;但他的销售过程并不顺利&#xff0c;在连续主动邀约之后效果不佳。 于是他…

2023/1/15 JS-变量提升与函数提升 执行上下文

1 变量提升与函数提升 变量声明提升 通过 var 声明的变量&#xff0c;在声明语句之前就可以访问到 - 值: undefined <script>console.log(a); // undefinedvar a 10 </script>函数声明提升 通过 function 声明的函数, 在声明语句之前就可以直接调用 - 值: 函数…

走近软件生态系统

生态系统&#xff08;Ecosystem&#xff09;原本是一个生物学术语&#xff0c;意思是由一些生命体相互依存、相互制约而形成的大系统&#xff0c;就像我们学生时代在生物学课堂上学到的那样。隐喻无处不在&#xff0c;人们把这个术语移植到了 IT 领域中来&#xff0c;比如我们常…

计算机基础(六):静态链接与动态链接

上一篇文章简单概括了 C语言程序经过编译&#xff0c;生成汇编语言、机器语言的基本过程。今天主要介绍其中链接阶段的实现思路。 静态链接 静态链接是将被依赖的代码片段复制到执行程序中&#xff0c;进行代码整合。因为我们在汇编代码中看到的是具体的符号&#xff0c;而且…

电路方案分析(十七)TI远程声控参考设计

远程声控参考设计 描述 CC2650远程控制设计为基于ZigBeeRF4CE™兼容的软件架构RemeTI™或蓝牙低能耗软件堆栈的快速测试、评估和开发远程控制应用程序提供了最佳基础。 该方案设计包含了CC2560远程控制的原理图和布局文件&#xff0c;以及一个演示了使用RF4CE和低能耗蓝牙的…