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

2023-05-16

步入正文

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring官方提供【CSRF攻击】解决方案 的相关文章

  • linux下搜狗拼音隐藏悬浮状态栏

    打开配置文件 vim config sogoupinyin conf env ini 找到以下内容 并修改为0 StatusAppearance 61 0 重启fcitx状态栏就消失了 killall fcitx fcitx
  • JavaScript笔记(2)

    7 对象 xff1a 对象的三种声明与调用方法 span class token comment 第一种声明方法 span span class token keyword let span ObjectName span class to
  • C++类与对象笔记

    C 43 43 类与对象笔记 本章主要讲了面向对象三大特性 xff1a 封装 xff0c 继承 xff0c 多态 C 43 43 认为万事万物都皆为对象 xff0c 对象上有其属性和行为 例如 xff1a 人可以作为对象 xff0c 属性有
  • C++基础笔记

    C 43 43 基础笔记 本章主要讲了在c的基础上 xff0c c 43 43 的拓扑基础的部分 xff0c 还有内存的分配 1 内存分区模型 C 43 43 程序在执行时 xff0c 将内存大方向划分为4个区域 1 代码区 xff1a 存
  • linux文件名匹配(通配符使用)

    当在使用命令行时 xff0c 有很多时间都用来查找你所需要的文件 xff0c 如ls find等 S h e l l提供了一套完整的字符串模式匹配规则 xff0c 或者称之为元字符 xff0c 当s h e l l遇到上述字符时 xff0c
  • Android指纹识别,兼容Android 6.0 - Android 11

    目录 前言 概览 1 类 2 权限 详细介绍 1 BiometricManager 属性和方法 是否可用的状态码 方法 2 BiometricPrompt 属性和方法 验证的结果常用错误码 不全 方法 实战 第一步 引入支持库 第二步 检查
  • Lottie-Android详解

    Lottie是什么 Lottie是Airbnb开源的一套跨平台的 完整的动画效果解决方案 xff0c 适用于 Android iOS Web 和 Windows 平台 xff0c 它解析使用 Bodymovin 导出为 json 的 Ado
  • 组合问题,n个元素分成k组-5

    题目要求 P n k 代表将n个元素分成k个非空分组集合的总集 例如 xff0c 当L 61 1 2 3 P xff08 3 xff0c 2 xff09 61 12 3 13 2 1 23 我们就假设此n个元素是从1到n P 4 3 61
  • FTPClient踩过的坑

    一 ftpClient enterLocalPassiveMode public static final int PASSIVE LOCAL DATA CONNECTION MODE 61 2 官网关于该常量的说明 xff1a A con
  • Camera基本属性了解及设置

    将camera肯定是要有预览界面来配合着才有激情 xff0c 不然无图无真相 那就讲的没有太大的激情 我们对camera的使用一般是在app里面有用到设置获取图片的时候提供一个拍照功能 xff0c 一般是跳转到系统的拍照界面使用camera
  • 验证码不显示的解决方法

    方法一 xff1a 出现上面的情况 xff0c 最基本的一个错误就是你很可能在php里面忘记安装gd模块了 window环境下面只需要在php ini文件里面找到 把前面的分号去掉就可以了 xff0c 重启apache后 xff0c 你就可
  • 纯NumPy代码从头实现简单的卷积神经网络

    在某些情况下 xff0c 使用 ML DL 库中已经存在的模型可能会很便捷 但为了更好地控制和理解模型 xff0c 你应该自己去实现它们 本文展示了如何仅使用 NumPy 库来实现 CNN 卷积神经网络 xff08 CNN xff09 是分
  • 一文搞懂结构体变量占用多大内存空间(详细)

    一 首先做一道例题感受一下 请问下面定义的结构体变量aa在计算机内存中占用多少字节 xff1f span class token macro property span class token directive hash span spa
  • harbor+trivy的安装使用——筑梦之路

    环境依赖 xff1a docker ce docker compose 这些部分的安装这里就不再赘述 创建证书和私钥 mkdir opt harbor ssl p 生成CA证书私钥 ca key openssl genrsa out ca
  • Thinkphp 6.0响应输出和重定向

    本节课我们来学习一下响应操作 xff0c 响应输出和重定向 一 xff0e 响应操作 1 响应输出 xff0c 有好几种 xff1a 包括 return json 和 view 等等 xff1b 2 默认输出方式是以 html 格式输出 x
  • log4net配置经验教训

    第一点 xff1a 权限问题 xff0c 一定要给要写入日志文件的目录宽松的权限 本人就是因为权限问题浪费了很多时间 xff08 因为iis user 的权限是相对低的 xff0c log4net又需要创建文件 xff0c 所以权限一定要给
  • Linux的目录结构

    目录说明bin存放二进制可执行文件 ls cat mkdir等 boot存放用于系统引导时使用的各种文件dev用于存放设备文件etc存放系统配置文件home存放所有用户文件的根目录lib存放跟文件系统中的程序运行所需要的共享库及内核模块mn
  • Python tkinter多进程多线程前邮箱,再用pyinstaller编译成exe

    写博客记录一下Python 用tkinter 多进程线程写成的邮箱应用 xff0c 只是一个简单的应用 xff0c 尝试进程调度 xff0c 并用pyinstaller打包成exe 注意 xff1a 1 平台环境win7 Python3 6
  • 终极解决python安装包时需要Microsoft Visual C++ 14.0的问题

    问题 Windows平台在pip install wordcloud包时需要安装 Microsoft Visual C 43 43 14 0 xff0c 而Microsoft Visual C 43 43 14 0 对应的是Microsof
  • Ubuntu18.04屏幕分辨率问题

    Ubuntu18 04屏幕分辨率问题 起因 本来昨天还好好的 xff0c 过了一夜 xff0c 就变了 xff0c 像极了咳咳 自行脑补 redwallbot 2小车上固定的屏幕 xff0c 屏幕分辨率本来应该是1920x1080的 xff

随机推荐

  • Android解决No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-and问题。

    问题说明 xff1a 导入下载的项目编译报错 错误如下 xff1a No toolchains found in the NDK toolchains folder for ABI with prefix mips64el linux an
  • Ubuntu Vim设置

    cp etc vim vimrc vimrc vi etc vim vimrc 针对所有用户 vi vimrc 针对user 34 关闭兼容功能 set nocompatible 34 显示行号 set number 34 编辑时 back
  • STM32CubeMX在freeRTOS中使用printf函数

    在usart h中添加 inlcude 34 stdio h 34 Includes include 34 main h 34 USER CODE BEGIN Includes include 34 stdio h 34 USER CODE
  • CUBEMX建立freeRTOS工程编译报错

    Middlewares Third Party FreeRTOS Source portable RVDS ARM CM3 portmacro h 167 error unknown type name 39 forceinline 39
  • STM32HAL库串口中断同时收发卡死

    在使用HAL库的过程中发现在串口中断的回显功能 xff08 将串口接收到的数据再发送出来 xff09 xff0c 总是执行几次后程序卡死 xff0c 无法正常回显 经过一系列查找后发现原因是STM32 HAL库在处理接收的时候会锁一下串口一
  • 二级指针作为形参简单实例分析

    指针是什么 xff1f 指针是程序数据在内存中的地址 xff0c 而指针变量是用来保存这些地址的变量 举例 int c 61 2 d 61 3 int pc 61 amp c pc是指针变量的存储内容 xff0c 也就是c的地址 pc就是对
  • OutputDebugString 封装;方便格式化

    自定义 xff1a OutputDebugString void MyOutputDebugString LPCTSTR lpszFmt if 1 如果不用了可以修改 va list args va start args lpszFmt i
  • 创建一个最简单的链表,插入和删除

    原创文章欢迎转载 创建一个链表 一 头插法创建链表 xff1a include lt stdio h gt struct list int num struct list next typedef struct list list sing
  • C语言循环链表创建,遍历,插入,删除,查找

    在开始程序之前说一个困扰的几天的东西 xff0c 在链表做形参的时候什么时候用 xff08 p xff09 什么时候用 xff08 p xff09 答案 xff1a 只要是要修改head指针必须传递head的地址 xff08 用 p xff
  • C语言顺序表的插入删除

    首先声明一个顺序表的结构 数组的第一个元素是0 xff0c 但是顺序表的第一个一般 从1 人为设定 开始 include lt stdio h gt include lt stdlib h gt define MAXSIZE 10 defi
  • 蓝牙HC05模块探究-设置AT指令

    蓝牙HC05是主从一体的蓝牙串口模块 xff0c 简单的说 xff0c 当蓝牙设备与蓝牙设备配对连接成功后 xff0c 我们可以忽视蓝牙内部的通信协议 xff0c 直接将将蓝牙当做串口用 当建立连接 xff0c 两设备共同使用一通道也就是同
  • WPF、C# iconfont图标字体只显示框框

    在我们写C 或者WPF 程序的时候 xff0c 引入字体图标的时候 xff0c 新手会出现下面这个问题 xff1b 下面说下常见的两个原因吧 xff1a 1 是文件路径定义的不对 xff1a lt TextBlock Text 61 34
  • Linux执行curl报错:Protocol htttp not supported or disabled in libcurl

    因为公司最近要用到docker xff0c 在学习过程中 构建了一个简单web镜像 xff0c 用于测试 通过curl访问地址时 xff0c 报错 随便百度下 xff0c 也没看懂 仔细一看 xff0c 原来是http写成htttp了 所以
  • Android 获取应用信息—PackageManager

    Android 的应用管理主要是通过PackageManagerService来完成的 PackageManagerService服务负责各种APK包的安装 卸载 优化和查询 PackageManagerService在启动时会扫描所有的A
  • eclipse自动补全不生效解决方法

    eclipse有时候设置了自动补全 xff0c 但明明设置了自动补全却没生效的解决办法 xff0c 按照图片上标注序号一步步进入Advanced页面后 xff0c 勾选第四步的三项选项即可 xff0c 重新生效 xff0c 如下
  • 史上最全的C++面试宝典(合集)

    参考 xff1a https www runoob com cplusplus cpp tutorial html 本教程旨在提取最精炼 实用的C 43 43 面试知识点 xff0c 供读者快速学习及本人查阅复习所用 目录 第一章 C 43
  • 电脑主板,显卡,CPU天梯图

    17年6月主板天梯图 18年2月显卡天梯图 18年3月CPU天梯图
  • sqlserver 批量删除存储过程

    sqlserver 2005一次只能删除一个存储过程 xff0c 如果多了 xff0c 需要很长时间才能删完 xff0c 所以写了一段语句 xff0c 直接就把当然数据库下所有用户自定义的存储过程给drop了 不过使用都请留心 xff0c
  • win7开启wifi共享(热点)

    1 首先在电脑左下方搜索cmd xff0c 以管理员身份运行 输入命令 xff1a netsh wlan set hostednetwork mode 61 allow ssid 61 4Gtest key 61 12345678 ssid
  • Spring官方提供【CSRF攻击】解决方案

    步入正文 Cookie cookie是我们常见用来保存用户态信息 xff0c cookie跟随我们的请求自动携带 在同一域名下的请求 xff0c cookie总是自动携带 用户态 当前登入者的用户信息 以上的特性会导致一个潜在漏洞 CSRF