csrf攻击原理与解决方法_前端

2023-11-07

1. CSRF 的攻击类型

CSRF,全称 Cross Site Request Forgery,跨站请求伪造,也被称为 XSRF、one-click attack 或者 session riding,是一种劫持受信任用户向服务器发送非预期请求的攻击方式。攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。与 XSS 相比,XSS 利用的是用户对指定网站的信任CSRF 利用的是网站对用户网页浏览器的信任

通常情况下,CSRF 攻击是攻击者借助受害者的 Cookie 骗取服务器的信任,可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击服务器,从而在并未授权的情况下执行在权限保护之下的操作。

来自知乎 @李上天 的回答中有一段生动描述:

如何用简洁生动的语言说明 XSS 和 CSRF 的区别?​www.zhihu.com
防盗系统启动: 妈妈: 给我看着衣服呀 小孩: 好的 小偷来了 正常工作: 小孩: 你是谁? 小偷: 我是张三 小孩:妈妈,有人偷衣服 妈妈: 谁? 小孩: 张三 小偷被抓 漏洞: 小孩: 你是谁? 小偷: 我叫逗你玩 小孩: 妈妈有人偷衣服呀 妈妈: 谁? 小孩: 逗你玩 妈妈: ... CSRF 是让用户在不知情的情况下,冒用其身份发起了一个请求 小偷: 你妈妈喊你去买洗衣粉

CSRF 原理很简单,甚至较于 XSS 显得更为单调。具体而言,包括以下 3 种攻击类型:

  1. GET 类型的 CSRF
  2. POST 类型的 CSRF
  3. 链接类型的 CSRF

GET 类型的 CSRF

这类攻击非常简单,只需要一个HTTP请求:

<img src="http://a.com/withdraw?amount=10000&for=hacker" >

在受害者访问含有这个 img 的页面后,浏览器会自动向 http://a.com 发出一次HTTP请求。http://a.com 就会收到包含受害者登录信息的一次跨域请求。

POST 类型的 CSRF

这种类型的 CSRF 利用起来通常使用的是一个自动提交的表单,如:

<form action="http://a.com/withdraw" method=POST>
    <input type="hidden" name="account" value="airing" />
    <input type="hidden" name="amount" value="10000" />
    <input type="hidden" name="for" value="hacker" />
</form>
<script> document.forms[0].submit(); </script>

访问该页面后,表单会自动提交,相当于模拟用户完成了一次 POST 操作。可见这种类型的 CSRF 与第一种一样,都是模拟请求,所以后端接口也不能将安全寄托在仅允许 POST 请求上。

链接类型的 CSRF

链接类型的CSRF并不常见,比起其他两种用户打开页面就中招的情况,这种需要用户点击链接才会触发,但本质上与前两种一样。这种类型通常是在论坛中发布的图片中嵌入恶意链接,或者以广告的形式诱导用户中招,攻击者通常会以比较夸张的词语诱骗用户点击,例如:

<a href="http://a.com/withdraw.php?amount=1000&for=hacker" taget="_blank">
 屠龙宝刀,点击就送! 
<a/>

由于之前用户登录了信任的网站A,并且保存登录状态,只要用户主动访问上面的这个页面,则表示攻击成功。

2. CSRF 的防御方法

CSRF 通常从第三方网站发起,被攻击的网站无法防止攻击发生,只能通过增强自己网站针对 CSRF 的防护能力来提升安全性。

上文中讲了 CSRF 的两个特点:

  1. CSRF(通常)发生在第三方域名
  2. CSRF 攻击者不能获取到 Cookie 等信息,只是使用

针对以上特点,CSRF 可制定以下两种防御策略:

  • 自动防御:阻止不明外域的访问
    • 同源检测
    • Samesite Cookie
  • 主动防御:提交时要求附加本域才能获取的信息
    • Synchrogazer Tokens
    • Double Cookie Defense
    • Custom Header

自动防御即利用 HTTP 协议固有的特性进行自动防护,而主动防御则需要通过编程手段进行防御。

2.1 CSRF 自动防御策略

2.1.1 同源检测

既然 CSRF 大多来自第三方网站,那么我们就直接禁止外域/不信任的域对我们发起请求。

在 HTTP 协议中,每一个异步请求都会携带两个 Header,用于标记来源域名:
* Origin Header
* Referer Header

通过验证这两个 Header 是否受信任从而实现同源检测。但这种方法并非万无一失,Referer 的值是由浏览器提供的,虽然 HTTP 协议上有明确的要求,但是每个浏览器对于 Referer 的具体实现可能有差别,并不能保证浏览器自身没有安全漏洞。使用验证 Referer 值的方法,就是把安全性都依赖于第三方来保障,从理论上来讲,这样并不是很安全。在部分情况下,攻击者可以隐藏,甚至修改自己请求的 Referer。我们在写爬虫之时,也通常会修改 Header 去绕过服务器的同源检测。在【基本功】 前端安全系列之二:如何防止CSRF攻击? | 美团技术团队 一文中具体分析了 Referer 的可信度与危险场景,这里限于篇幅便不再赘述。

综上所述,同源验证是一个相对简单的防范方法,能够防范绝大多数的 CSRF 攻击。但这并不是万无一失的,对于安全性要求较高,或者有较多用户输入内容的网站,我们就要对关键的接口做额外的防护措施,也就是下文即将说到的主动防御策略。

2.1.2 Samesite Cookie

为了从源头上解决这个问题,Google 起草了一份草案 来改进 HTTP 协议,那就是为 Set-Cookie 响应头新增 Samesite 属性,它用来标明这个 cookie 是个“同站 cookie”,同站 cookie 只能作为第一方 cookie,不能作为第三方 cookie。SameSite 有两个属性值,分别是 Strict 和 Lax。

  • Samesite=Strict:严格模式,表明这个 cookie 在任何情况下都不可能作为第三方 cookie,绝无例外。
  • Samesite=Lax:宽松模式,比 Strict 放宽了点限制。假如这个请求是同步请求(改变了当前页面或者打开了新页面)且同时是个 GET 请求,则这个 cookie 可以作为第三方 cookie。

但 Samesite Cookie 也存在着一些问题:

  1. Samesite 的兼容性不是很好,现阶段除了从新版 Chrome 和 Firefox 支持以外,Safari 以及 iOS Safari 都还不支持,现阶段看来暂时还不能普及。
  2. 而且,SamesiteCookie 目前有一个致命的缺陷,不支持子域。例如,种在 http://blog.ursb.me 下的 Cookie,并不能使用 http://ursb.me 下种植的 SamesiteCookie。这就导致了当我们网站有多个子域名时,不能使用SamesiteCookie 在主域名存储用户登录信息。每个子域名都需要用户重新登录一次。这是不实际的。

2.2 CSRF 主动防御策略

CSRF 主动防御措施有以下三种:

  1. Synchronizer Tokens:通过响应页面时将 token 渲染到页面上,在 form 表单提交的时候通过隐藏域提交上来。
  2. Double Cookie Defense:将 token 设置在 Cookie 中,在提交 POST 请求的时候提交 Cookie,并通过 header 或者 body 带上 Cookie 中的 token,服务端进行对比校验。
  3. Custom Header:信任带有特定的 header(例如 X-Requested-With: XMLHttpRequest)的请求。这个方案可以被绕过,所以 rails 和 django 等框架都放弃了该防范方式。

所以下文主要讲讲前面两种防御方式。

2.2.1 Synchrogazer Token

Synchrogazer Token,即同步表单的 CSRF 校验。CSRF 攻击之所以能够成功,是因为服务器误把攻击者发送的请求当成了用户自己的请求。那么我们可以要求所有的用户请求都携带一个 CSRF 攻击者无法获取到的 Token。服务器通过校验请求是否携带正确的 Token,来把正常的请求和攻击的请求区分开,也可以防范 CSRF 的攻击。

具体而言,分为以下三个步骤:

  1. 将 CSRF Token 输出到页面中
  2. 页面提交的请求携带这个 Token,通常隐藏在表单域中作为参数提交,或拼接在 URL 后作为 query 提交。
  3. 服务器验证 Token 是否正确

当用户从客户端得到了 Token,再次提交给服务器的时候,服务器需要判断 Token 的有效性,验证过程是先解密 Token,对比加密字符串以及时间戳,如果加密字符串一致且时间未过期,那么这个 Token 就是有效的。这种 Token 的值通常是使用 UserID、时间戳和随机数,通过加密的方法生成。这样的加密既能验证请求的用户、请求的时间,又能保证 Token 不容易被破解。个人在项目中使用以下加密方式,仅供参考:

import md5 from 'md5'

export const MESSAGE = {
  OK: {
    code: 0,
    message: '请求成功',
  },
  TOKEN_ERROR: {
    code: 403,
    message: 'TOKEN失效',
  },
}

const md5Pwd = (password) => {
  const salt = 'Airing_is_genius'
  return md5(md5(password + salt))
}

export const validate = (res, check, ...params) => {

  for (let param of params) {
    if (typeof param === 'undefined' || param === null) {
      return res.json(MESSAGE.PARAMETER_ERROR)
    }
  }

  if (check) {
    const uid = params[0]
    const timestamp = params[1]
    const token = params[2]

    if (token !== md5Pwd(uid.toString() + timestamp.toString() + KEY))
      return res.json(MESSAGE.TOKEN_ERROR)
  }
}

这种方法要比之前检查 Referer 或者 Origin 要安全一些,Token 可以在产生并放于 Session 之中,然后在每次请求时把 Token 从 Session 中拿出,与请求中的 Token 进行比对。但是有以下两点需要注意。

  1. Session Vs Cookie若可以将 token 存放到 Session 中,却是一个不错的选择**。
  2. 刷新 CSRF Token:当 CSRF token 存储在 Cookie 中时,一旦在同一个浏览器上发生用户切换,新登陆的用户将会依旧使用旧的 token(之前用户使用的),这会带来一定的安全风险,因此在每次用户登陆的时候都必须刷新 CSRF token

2.2.2 Double Cookie Defence

Double Cookie Defence,中文译作双重 Cookie 验证

在 Session 中存储 CSRF Token 比较繁琐,而且不能在通用的拦截上统一处理所有的接口。那么另一种防御措施是使用双重提交 Cookie。利用 CSRF 攻击不能获取到用户 Cookie 的特点,我们可以要求 Ajax 和表单请求携带一个 Cookie 中的值。

  1. 在用户访问网站页面时,向请求域名注入一个Cookie,内容为随机字符串。
  2. 在前端向后端发起请求时,取出Cookie,并添加到URL的参数中。
  3. 后端接口验证Cookie中的字段与URL参数中的字段是否一致,不一致则拒绝。

此方法相对于 CSRF Token 就简单了许多。可以直接通过前后端拦截的的方法自动化实现。后端校验也更加方便,只需进行请求中字段的对比,而不需要再进行查询和存储 Token。但是它并没有被大规模应用,尤其在大型网站上,存在着严重的缺陷。举一个栗子 :

由于任何跨域都会导致前端无法获取 Cookie 中的字段(包括子域名之间),所以当用户访问我的 me.ursb.me 之时,由于我的后端 api 部署在 api.ursb.me 上,那么在 me.ursb.me 用户拿不到 api.ursb.me 的 Cookie,也就无法完成双重 Cookie 验证。依此,我们的 Cookie 放在了 ursb.me 主域名下,以保证每个子域名都可以访问。但 ursb.me 下其实我还部署了很多其他的子应用,如果某个子域名 xxx.ursb.me 存在漏洞,虽然这个 xxx.ursb.me 可能没有什么值得窃取的信息,但是攻击者可以修改 ursb.me 下的 Cookie,从而实现 XSS 攻击,并利用篡改的 Cookie 对 me.ursb.me 发起 CSRF 攻击。同时,为了确保 Cookie 传输安全,采用这种防御方式的最好确保用整站 HTTPS 的方式,如果还没切 HTTPS 的使用这种方式会有风险。

以下是来自 【基本功】 前端安全系列之二:如何防止CSRF攻击? | 美团技术团队 的关于双重 Token 验证的总结:

优点:

  • 无需使用 Session,适用面更广,易于实施。
  • Token 储存于客户端中,不会给服务器带来压力。
  • 相对于 Token,实施成本更低,可以在前后端统一拦截校验,而不需要一个个接口和页面添加。

缺点:

  • Cookie 中增加了额外的字段。
  • 如果有其他漏洞(例如XSS),攻击者可以注入Cookie,那么该防御方式失效。
  • 难以做到子域名的隔离。
  • 为了确保Cookie传输安全,采用这种防御方式的最好确保用整站 HTTPS 的方式,如果还没切 HTTPS 的使用这种方式也会有风险。

参考资料

  • 安全 | egg
  • 【基本功】 前端安全系列之二:如何防止CSRF攻击? | 美团技术团队
  • CSRF 攻击的应对之道 | IBM Developer
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

csrf攻击原理与解决方法_前端 的相关文章

  • LeetCode-679.24 点游戏、深度优先搜索算法DFS

    来源 力扣 LeetCode 题目分析 括号运算符仅仅表达了一个运算顺序 可以不用考虑 实际的运算类型就 4 种 一共只有 4 个数 因此所有组合的可能性是有限的 DFS 算法就是对当前的所有可能的操作进行枚举 当前的操作即从可选的数字中挑
  • 国内获取Docker镜像缓慢

    国内获取Docker镜像时 访问 https hub docker com 速度缓慢 只有几十K左右 这种情况可以使用国内的一些docker镜像 例如 网易蜂巢 阿里巴巴 LUG USTC等 此处介绍使用中国科学技术大学 LUG USTC
  • 【分享】免费的AI绘画网站(5个)

    哈喽 大家好 我是木易巷 随着人工智能技术的不断发展 越来越多的AI绘画软件开始涌现 如果你想要免费享受AI绘画的乐趣 那你可要好好看下面的内容 Vega AI创作平台 入口 https rightbrain art 一款专业的人工智能创作
  • AI 工具合辑盘点(八)持续更新 之 AI 面部生成工具和AI 角色生成工具

    一 AI 面部生成工具 需要一张真实人物的肖像画来用于你的营销材料 正在寻找具有特定面部特征的模特 但你的预算有限 正在创建你的买家人物 但不想从互联网上窃取图片 如果是这样 也许AI面部生成器可以作为解决方案 它们利用先进的图像处理技术
  • springboot 项目 docker 启动镜像 读不到application配置

    Dockerfile FROM openjdk 17 RUN cd RUN mkdir p config 删除旧jar包 RUN rm rf springboot3 jar 重新复制jar包 ARG JAR FILE ADD target
  • Maven问题:To see the full stack trace of the errors, re-run Maven with the -e switch.

    报错如下 ERROR gt Help 1 ERROR ERROR To see the full stack trace of the errors re run Maven with the e switch ERROR Re run M
  • C语言之详解静态变量static

    在C语言中static是用来修饰变量和函数的 这篇文章详细介绍了static主要作用 文章中有详细的代码实例 需要的朋友可以参考阅读 在C语言中 static是用来修饰变量和函数的 static主要作用为 1 修饰局部变量 静态局部变量 2
  • 在idea中快速构建方法的说明注释,带有参数信息

    在方法上面输入 然后按Ctrl enter即可 下面都是自动生成的内容 param request param response param handler return throws Exception Override public b
  • git命令超实用总结(23条超实用命令)

    本文总结了常见的23个git使用场景的处理方法 足够应对日常学习工作中对git的使用 文章目录 1 添加SSH验证免登陆 2 将本地项目上传GitHub 2 1 如果是新项目 本地还没有代码 2 2 如果想直接使用远程的代码 2 3 如果是
  • Android studio 3.5 debug 包不能安装

    debug模式下编译出的apk无法安装 可在根目录gradle properties中配置 android injected testOnly false
  • HTTP 隧道

    本文摘自书籍 HTTP 权威指南 此系列文章对应 github地址 隧道 可以通过 HTTP 应用程序访问使用非 HTTP 协议的应用程序 Web 隧道允许用户通过 HTTP 连接发送非 HTTP 流量 这样就可以在 HTTP 上捎带其他协
  • 2023牛客暑期多校训练营7 I We Love Strings

    https ac nowcoder com acm contest 57361 I 分治 容斥原理 include
  • [es6] 模板字符串内添加if判断

    我之前一只知道模板字符串中可以用三目运算符做判断 但今天有个需求要在模板字符串中添加if条件语句 于是百度了一下 在此记录一下 直接看代码吧 var html div class p 1 p p 2 p p 3 p p function i
  • Mybatis返回自增主键id的值,2种方式

    1 方式一 不建议使用 有BUG的方式 通过useGeneratedKeys true keyProperty id 来设置返回新的id值 这里有个问题就是 通过这种方式插入的值 经常会返回1 原因是因为他这里的意思是返回当前影响的行数 不
  • lc marathon 7.16

    文章目录 138 复制带随机指针的链表 https leetcode cn problems copy list with random pointer 剑指 Offer II 092 翻转字符 https leetcode cn prob
  • c++ 自定义时间格式

    1 自定义时间格式 我们可以使用strftime 函数将时间格式化为我们想要的格式 它的原型如下 size t strftime char strDest size t maxsize const char format const str
  • 关于HR系统升级为集团版的设计总结

    刚刚完了公司HR系统的升级 系统实现了从单一公司使用到多公司使用的转变 在升级的一个多月的时间内 虽然很苦 但感觉自已在系统架构上受益非浅 具体有以下感悟 一 MVC还是很重要 系统框架是五年前用delphi设计的 采用的基类加扩展类的模式
  • fluent p1模型_Fluent辐射传热模型理论以及相关设置(一)

    原标题 Fluent辐射传热模型理论以及相关设置 一 本文来源于网络 原作者 Libo CHen 感谢作者的辛苦整理和撰写 1概述 在传热的仿真中 有时候会不可避免的涉及到辐射传热 而我们对Fluent中辐射模型的了解甚少 很难得到可靠的计
  • 关于Unity-Web的Development build。

    Unity转手游之后是否该勾选development Build 首先看一看官方文档的解释 Development Build When you check the Development Build checkbox Unity gene

随机推荐

  • 【杂记】EMC、EMI、EMS、TVS、ESD概念学习总结

    注 杂记 系列为日常网搜资料的简单堆砌而积累成之 如有错误恭谢指出 标识为 原创 其实不完全是 只是多引用再整理 大都引自网络 侵删 EMC EMC Electromagnetic Compatibility 属于概念 为电磁兼容性 电磁兼
  • java 中unsigned类型的转换

    java 中unsigned类型的转换
  • oh-my-zsh安装与常用插件

    zsh 介绍 工欲善其事 必先利其器 zsh也是一种 shell 兼容最常用的 bash 这种 shell 的命令和操作 bash 虽然很标准 但是自己日常使用方便更重要 oh my zsh 提供了丰富的插件和提 安装 先使用命令查看系统支
  • whisper:robust speech recognition via large-sacle weak supervision

    OpenAI Whisper 精读 论文精读 45 哔哩哔哩 bilibili更多论文 https github com mli paper reading 视频播放量 68331 弹幕量 327 点赞数 2332 投硬币枚数 1192 收
  • QJsonObject的使用示例

    介绍 负责封装JSON对象 是键 值对列表 其中键是惟一的字符串 值由QJsonValue表示 1 QJsonObjec 封装了Json里的对象 接口与QMap相似 都具有size insert 和remove 等操作 还可以使用标准C 迭
  • SQL Server(三)-查询数据(2)

    函数与分组查询数据 一 系统函数 在SQL Server 2008中系统函数是指在SQL Server 2008中自带的函数 主要分为聚合函数 数据类型转换函数 日期函数 数学函数及其他一些常用的函数 1 聚合函数 对一组值进行计算 然后返
  • 雅思词汇表8000词版_你别不信,雅思光靠背单词也能上6.5!

    点击上方蓝字关注我哦 打算备考雅思 大家都是知道IELTS考试对词汇量要求是比较高的 如果自身的英语基础薄弱 想短时间内在雅思成绩上有所突破是很困难的一件事情 因此很多考生会 病急乱投医 购买各式各样雅思词汇手册进行疯狂记忆 每本单词手册都
  • Keil 重定向 fputc 函数 以及 printf 函数的代码尺寸测试

    本文的开发环境为 Keil Cortex M3 内核处理器 重定向 fputc 函数方法 如果想使用库函数 printf 必须要将 fputc 重定向到自己的串口上 术语 重定向 可以理解为用户重写 fputc 函数 在重写的函数体内调用自
  • vulnhub-KIOPTRIX: LEVEL 1.3 (#4)-KioptrixVM4靶场

    以下演示均在测试环境进行 遵纪守法 靶场下载地址 Kioptrix Level 1 3 4 VulnHub 镜像下载解压之后是一个 vhd文件 需要新建虚拟机 虚拟机操作系统任选一个linux系列的系统 一直下一步 到了设置磁盘 按照截图设
  • Qt系列文章之(十) ui文件的使用

    上一篇文章在主函数中构造了一个简单的主窗口界面 继承了一些基本元素 如菜单栏 工具栏 悬浮窗口 主界面等元素 不过这些元素都是在栈区开辟的临时变量 放在主函数里面来实现 这不是一种标准的UI界面开发手段 一般在界面项目开发之中有几个典型的开
  • PyCharm远程连接失败、错误,报错:Can‘t connect...【解决方法与错误分析】

    学习网站推荐 前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住分享一下给大家 点击跳转到网站 文章目录 一 前言 二 报错 2018版 2020版 三 错误分析 我的错误原因 其他3种可能因粗心导致的原因 四 如果你不想再
  • HTTPX从入门到放弃

    1 什么是HTTPX HTTPX是一款Python栈HTTP客户端库 它提供了比标准库更高级别 更先进的功能 如连接重用 连接池 超时控制 自动繁衍请求等等 HTTPX同时也支持同步和异步两种方式 因此可以在同步代码和异步代码中通用 HTT
  • Swift语法学习--协议基础

    文章目录 协议定义 typealias关键词类型定义新的名称 associatedtype增加协议功能 协议定义 typealias关键词类型定义新的名称 不做赘述 typealias Distance Double typealias P
  • 游戏对象与图形基础

    游戏对象与图形基础 这是有游戏编程的第四次作业 对MVC深入 文章目录 游戏对象与图形基础 说明文档 作业内容 1 基本操作演练 建议做 2 编程实践 需求分析 新版的设计与实现 说明文档 本次实验完成了所有基本要求 尽量将步骤展示出 闪光
  • java中把判断大小的字符串转换成可判断的布尔值

    ScriptEngineManager manager new ScriptEngineManager ScriptEngine se manager getEngineByName js String str 1 lt 3 boolean
  • OpenCV

    OpenCV polylines绘制多边形 1 四边形 Mat image 300 300 CV 8UC3 Scalar 255 255 255 300X300大小的白色图像 Point pnt 1 4 Point 100 100 左上角
  • 【计算机网络】Linux环境中的网络套接字编程

    文章目录 前言 一 预备知识 理解源IP地址和目的IP地址 认识端口号 认识UDP协议和TCP协议 了解网络字节序 二 socket 套接字 socket 常见API sockaddr 和 sockaddr in 三 UDP Socket编
  • .Net web service studio的使用

    无意间发现有个比较好的工具 它很小才几十K而已 真的很轻量 就是web service studio 可以用来测试web service 因为web service因为其返回结果的特殊性以及请求的不一样 平时也很难去测试这个接口到底能否使用
  • 系统分析与设计-用例建模之业务建模方法

    系统分析与设计 用例建模之业务建模方法 文章目录 系统分析与设计 用例建模之业务建模方法 使用 UMLet 建模 根据订旅馆建模文档 根据课程练习 投递员使用投递箱给收件人快递包裹 的业务场景 根据上述流程 给出快递柜系统最终的用例图模型
  • csrf攻击原理与解决方法_前端

    1 CSRF 的攻击类型 CSRF 全称 Cross Site Request Forgery 跨站请求伪造 也被称为 XSRF one click attack 或者 session riding 是一种劫持受信任用户向服务器发送非预期请