当前位置: 首页 > news >正文

[漏洞篇]CSRF漏洞详解

[漏洞篇]CSRF漏洞详解

免责声明: 本文主要讲解漏洞原理,以及防御手段,旨在帮助大家更好的了解漏洞危害以及不法分子常见的利用方式,同时帮助大家了解开发中所需要关注的点,切勿拿来做违法事情,否则后果自负。

一、介绍

概念

CSRF(Cross-Site Request Forgery,跨站请求伪造),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF 。它是一种常见的 Web攻击方式,是一种劫持用户在当前已登录的Web应用程序上执行非本意操作一种攻击。

  • 说的直白一点就是:别人盗用(劫持)你的身份去做坏事.
    (1)别人–>这里指的是攻击者
    (2)你---->A站(web服务器)上注册的合法用户(客户端)
    (3)做坏事—>去请求合法站点A(比如web服务器)存在CSRF攻击的URL,实现类似发送恶意邮件/转账/创建账户/修改密码等"你不希望执行"操作.

CSRF漏洞与SSRF漏洞区别:

CSRF(Cross-Site Request Forgery 跨站请求伪造):黑客盗用用户身份向服务器发送请求。伪造用户身份向服务器发送请求,并不会攻击到内网服务。
SSRF (Server-Side Request Forgery 服务器端请求伪造) :黑客盗用服务器身份向内网其他服务发送请求。模仿内网服务器直接通过给URL发送攻击代码攻击到服务器所在内网里的机器或服务。

CSRF漏洞与XSS漏洞区别:

CSRF是借用户的权限完成攻击,攻击者并没有拿到用户的权限(不知道用户的cookie等信息,只是借用用户之手发起请求),而XSS是直接盗取到了用户的权限(直接获取到了用户的cookie),然后实施破坏。

危害

  • 账户劫持:修改密码、绑定邮箱,导致用户失去账户控制权。
  • 资金窃取:触发转账、支付等金融操作。
  • 数据篡改:更改用户资料、发布恶意内容(如社交平台发帖)。
  • 业务逻辑滥用:利用用户权限执行特权操作(如管理员功能)。
  • 组合攻击:与XSS结合扩大攻击面(如窃取Token后绕过CSRF防御)。

示例:用户登录银行网站后访问恶意页面,页面包含一个自动提交的表单,请求银行转账至攻击者账户。

因此一些银行或其他敏感信息app或网页,才会在用户登录账号后,提示用户让用户不要离开本软件进行操作。

原理

漏洞原理图:
在这里插入图片描述

1. 漏洞产生原因

(1)http协议使用session在服务端保存用户的个人信息,客户端浏览器用cookie标识用户身份;
(2)cookie的认证只能确保是某个用户发送的请求,但是不能保证这个请求是否是"用户自愿的行为".
(3)这时,用户登录了某个web站点,同时点击了包含CSRF恶意代码的URL,就会触发CSRF

2. 利用条件

(1)用户必须登录A网站,生成了cookie
(2)登录的同时访问了恶意URL(包含CSRF恶意代码的URL).

3. CSRF与XSS关系

CSRF是借用户的权限完成攻击,攻击者并没有拿到用户的权限,而XSS是直接盗取到了用户的权限,然后实施破坏。

(1)XSS主要用户获取用户的cookie信息,达到控制客户端的目的

XSS---->把你的腰牌(用户身份象征也就是cookie)偷到手,黑客自己去搞破坏.
CSRF主要是劫持用户身份,让客户端做一些不愿意做的事.
CSRF---->拿刀劫持你,"借助你的身份"来帮黑客做事.

(2)危害上来说,XSS更大;
(3)从应用难度上来说:CSRF需要满足登录某网站的状态,同时访问了恶意的URL,应用条件比较苛刻。XSS只要一次点击或者存储到服务器即可.

二、实战演示

靶场搭建

# 安装docker(也可通过安装docker desktop软件来安装docker)
apt install docker.io# 通过docker搭建靶场
docker run -d -p 8765:80 8023/pikachu-expect:latest

浏览器输入下面地址,访问靶场页面:http://localhost:8765/vul/csrf/csrf.php

初始化靶场:
在这里插入图片描述

实战

Pass 01:CSRF Get

  1. 访问靶场地址:http://localhost:8765/vul/csrf/csrfget/csrf_get_login.php
  2. 根据提示进行登录
    在这里插入图片描述
  3. 进入用户信息页面修改个人信息,点击submit,并进行抓包(这里我使用Burpsuite演示)
    在这里插入图片描述
    在这里插入图片描述
  4. 根据上面抓包信息,构造修改用户信息URL,然后诱导用户点击。假设这里将用户phonenum改为xx
http://localhost:8765/vul/csrf/csrfget/csrf_get_edit.php?sex=girl&phonenum=xx&add=test&email=test&submit=submit

浏览器访问我们构造的攻击URL,查看页面效果:
在这里插入图片描述
在这里插入图片描述

因为我们浏览器已经有用户的cookie信息,请求时会自动带上用户的cookie,所以服务器会认为是用户自己主动的修改操作,因此通过GET能直接修改成功。

Pass 02:CSRF Post

渗透神器Burpsuite教程地址:https://blog.csdn.net/weixin_45565886/article/details/144973331

  1. 访问靶场地址:http://localhost:8765/vul/csrf/csrfpost/csrf_post.php
  2. 步骤与上面一致,登录之后然后手动操作,点击修改用户个人信息,同时抓包(这里抓包采用Brupsuite,方便后续构造poc)
    在这里插入图片描述
    在这里插入图片描述
  3. 构造漏洞Poc
    在这里插入图片描述
    在这里插入图片描述
    点击页面右下角的Test in browser,复制网址,然后在配置了Burpsuite代理的浏览器中打开:
    在这里插入图片描述
    模拟用户操作(点击恶意网页按钮),查看效果:
    在这里插入图片描述
    成功修改:
    在这里插入图片描述

这里更隐蔽的话,还可以将表单作为自动提交,即:访问该页面就提交,而并非用户主动点击,实现更无感。
📢注意:因此大家一定不要随意访问来源不明页面,点击不明按钮。

Pass 03:CSRF Token

  1. 访问靶场页面:http://localhost:8765/vul/csrf/csrftoken/token_get.php
  2. 依然是登录之后然后手动操作,点击修改用户个人信息,同时抓包
    在这里插入图片描述
  3. 这里我们重新请求,查看token值,发现token值是变化的
    在这里插入图片描述
  4. 因此我们直接请求是不行的,需要mock这里的token,破解这里token生成的规则,这里从Burpsuite的插件市场安全csrf token分析插件。

Csrf token原理:每次访问页面的时候,在后端生成一个token然后存放在SESSION中。并且将token渲染到表单中。
然后提交表单的时候,就会携带这个token,后端接收到这个token的时候和session中的token进行对比
如果一致:请求合法
如果不一致:请求失效
解释:

  1. 银行(服务端)每次办业务时给你一个一次性密码(Token)。
  2. 你提交请求时必须附带这个密码(否则银行拒绝操作)。
  3. 骗子即使诱导你点击链接,也无法拿到这个密码,因此攻击失败。

来到Burpsuite插件市场,安装csrf token插件:
在这里插入图片描述
插件安装成功后,可以看到Burpsuite顶部菜单栏多了一个CSRF Token Tracker:
在这里插入图片描述
5. 配置插件,分析对应网站的token

这里的Host配置IP或域名即可,不用带上端口信息
我本地配置了Host文件,因此下面的插件配置Host为www.pikaku.com
在这里插入图片描述

在这里插入图片描述
6. 重新抓修改用户请求包,并发送到Repeater重放模块
在这里插入图片描述
来到重放模块,修改用户信息,并重新发送请求
在这里插入图片描述

点击Send后,重新刷新页面查看效果:
在这里插入图片描述
在这里插入图片描述

查看CSRF Token Tracker插件信息:
在这里插入图片描述

CSRF Token Tracker大致原理:插件通过异步去先一步去获取token的值,然后将请求的token值给替换了。
但是这个地方仅仅做实验应该是可以的,真实场景实用性不强(真实场景的token没有这么好破解)。

三、绕过手段

1. Referer检查绕过

  • 利用浏览器隐私设置(禁用Referer)或HTTPS→HTTP降级导致Referer缺失。
  • 构造子域名或路径欺骗(如attack.com/?target.com)。

2. CSRF Token破解

  • 通过XSS漏洞窃取Token。
  • 预测或复用Token(如Token未绑定会话或过期时间过长)。

3. JSONP/CORS滥用

  • 利用未正确配置的JSONP接口发送跨域请求。
  • 通过CORS信任任意源发起携带Cookie的请求。

4. 同源策略绕过

  • 使用+window.open跨域提交。
  • 利用Flash插件(已逐渐淘汰)发送请求。

5. HTTP方法篡改

  • 将POST请求转换为GET(如通过URL参数传递敏感操作)。

四、防御手段

最佳实践:

  • 纵深防御:组合Token、SameSite Cookie、Referer检查等多层防护。
  • 敏感操作隔离:关键功能使用独立域名,减少Cookie携带风险。
  • 定期审计:检查Token生成、存储逻辑,确保无漏洞。
  • 安全教育:提升开发人员对CSRF及关联漏洞(如XSS)的认知。

1. CSRF Token

  • 机制:服务器生成随机Token,嵌入表单或请求头,提交时验证。
  • 实践:
    • Token绑定会话,每次请求更新(防复用)。
    • 对敏感操作强制使用POST/PUT/DELETE方法。

详细解释:

  • CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于 cookie 中,因此黑客可以在不知道这些验证信息的情况下直接利用用户自己的 cookie 来通过安全验证。要抵御 CSRF关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中。
  • 因此我们可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。
  • 这种方法要比检查 Referer要安全一些,token 可以在用户登陆后产生并放于 session 之中,然后在每次请求时把 token 从 session 中拿出,与请求中的 token 进行比对,但这种方法的难点在于如何把 token 以参数的形式加入请求。
  • 对于 GET 请求,token 将附在请求地址之后,这样 URL 就变成 http://url?csrftoken=tokenvalue。 而对于 POST 请求来说,要在 form 的最后加上 ,这样就把 token 以参数的形式加入请求了。
  • 但是,在一个网站中,可以接受请求的地方非常多,要对于每一个请求都加上 token 是很麻烦的,并且很容易漏掉,通常使用的方法就是在每次页面加载时,使用 javascript 遍历整个 dom 树,对于 dom 中所有的 a 和 form 标签后加入 token。这样可以解决大部分的请求,但是对于在页面加载之后动态生成的 html 代码,这种方法就没有作用,还需要程序员在编码时手动添加 token。
  • 该方法还有一个缺点是难以保证 token 本身的安全。特别是在一些论坛之类支持用户自己发表内容的网站,黑客可以在上面发布自己个人网站的地址。由于系统也会在这个地址后面加上 token,黑客可以在自己的网站上得到这个 token,并马上就可以发动 CSRF 攻击。
  • 为了避免这一点,系统可以在添加 token 的时候增加一个判断,如果这个链接是链到自己本站的,就在后面添加 token,如果是通向外网则不加。

不过,即使这个 csrftoken 不以参数的形式附加在请求之中,黑客的网站也同样可以通过 Referer 来得到这个 token 值以发动 CSRF 攻击。这也是一些用户喜欢手动关闭浏览器 Referer 功能的原因。

2. 自定义HTTP头

  • 实现:通过前端脚本(如Ajax)添加自定义头(如X-Requested-With)。
  • 原理:跨域请求默认无法添加自定义头(受CORS限制)。

详细解释:

  • 这种方法也是使用 token 并进行验证,和上一种方法不同的是,这里并不是把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。
  • 这样解决了上种方法在请求中加入 token 的不便,同时,通过XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担心 token 会透过 Referer 泄露到其他网站中去。
    然而这种方法的局限性非常大,XMLHttpRequest 请求通常用于 Ajax 方法中对于页面局部的异步刷新,并非所有的请求都适合用这个类来发起,而且通过该类请求得到的页面不能被浏览器所记录下,从而进行前进,后退,刷新,收藏等操作,给用户带来不便。
    另外,对于没有进行 CSRF 防护的遗留系统来说,要采用这种方法来进行防护,要把所有请求都改为 XMLHttpRequest 请求,这样几乎是要重写整个网站,这代价无疑是不能接受的。

3. SameSite Cookie属性

  • 作用:限制Cookie在跨站请求中的发送。SameSite是服务端控制的安全机制,用户侧无法修改。
    • Strict:完全禁止跨站携带Cookie(适用于关键操作)。
    • Lax:允许安全跨站导航(如GET请求)。
    • None:无论什么请求,都携带cookie
      在这里插入图片描述

详细解释:Chrome 51 开始,浏览器的 Cookie 新增加了一个SameSite属性,用来防止 CSRF 攻击和用户追踪。SameSite Cookie 有三个属性:Lax、Strict 和 None,它们定义了不同的跨站请求行为。

  • Strict(严格的):Strict最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。

这个规则过于严格,可能造成非常不好的用户体验。比如,当前网页有一个 GitHub 链接,用户点击跳转就不会带有 GitHub 的 Cookie,跳转过去总是未登陆状态。

  • Lax(松懈的):Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。

导航到目标网址的 GET 请求,只包括三种情况:链接,预加载请求,GET 表单。设置了Strict或Lax以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性

  • None:在这种模式下,无论请求是如何发起的,都会携带 Cookie。

Chrome 计划将Lax变为默认设置。这时,网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效

4. 检查Referer/Origin头

  • 验证来源:确保请求来自同一域名或可信源。
  • 注意:需处理Referer为空的情况(如HTTPS页面引用HTTP资源)。

详细解释:

  • 根据 HTTP 协议,在 HTTP 头中有一个字段叫Referer,它记录了该 HTTP 请求的来源地址。在通常情况下,访问一个安全受限页面的请求来自于同一个网站,比如需要访问 :http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory
  • 这时,该转账请求的 Referer 值就会是转账按钮所在的页面的 URL,通常是以 bank.example 域名开头的地址。而如果黑客要对银行网站实施 CSRF 攻击,他只能在他自己的网站构造请求,当用户通过黑客的网站发送请求到银行时,该请求的 Referer 是指向黑客自己的网站。

因此,要防御 CSRF 攻击,银行网站只需要对于每一个转账请求验证其 Referer 值,如果是以 bank.example 开头的域名,则说明该请求是来自银行网站自己的请求,是合法的。如果 Referer 是其他网站的话,则有可能是黑客的 CSRF 攻击,拒绝该请求。

5. 二次确认

  • 验证码/密码:关键操作前要求用户交互(如输入验证码、密码)。
  • 权衡:安全性与用户体验的平衡。

详细解释:验证码被认为是对抗CSRF攻击最简洁而有效的防御方法。

  • CSRF攻击的过程,往往是在用户不知情的情况下构造了网络请求。而验证码,则强制用户必须与应用进行交互,才能完成最终请求。因此在通常情况下,验证码能够很好地遏制CSRF攻击。
  • 但是验证码并非万能。很多时候,出于用户体验考虑,网站不能给所有的操作都加上验证码。因此,验证码只能作为防御CSRF的一种辅助手段,而不能作为最主要的解决方案。

6. 框架内置防护

  • 工具:Spring Security、Django CSRF中间件等自动处理Token。
  • 配置:确保所有状态变更请求启用防护。

7. 提升安全防范意识

  • 对普通用户来讲,不要点击来历不明的链接或图片;养成定时退出的好习惯;安装安全防护软件等

参考文章:
https://www.ruanyifeng.com/blog/2019/09/cookie-samesite.html

相关文章:

  • visual Studio+Qt插件检查内存泄漏
  • opencv HSV的具体描述
  • div(HTML标准元素)和view(微信小程序专用组件)的主要区别体
  • FPGA入门学习Day1——设计一个DDS信号发生器
  • Python开发环境打包迁移指南:离线与在线环境的完美解决方案
  • 数据结构之BFS广度优先算法(腐烂的苹果)
  • 【c语言】——深入理解指针2
  • 【模块化拆解与多视角信息6】自我评价:人设构建的黄金50字——从无效堆砌到精准狙击的认知升级
  • 【力扣】重排链表
  • C++ static的使用方法及不同作用
  • 你知道微生物是如何调控植物功能基因的吗?
  • 供水公司一体化抄表营业收费系统
  • 在 Kali Linux 上安装 Java OpenJDK 8(详细指南)
  • 电商|基于java+vue的农业电商系统(源码+数据库+文档)
  • oracle数据库启动阶段 NoMount / Mount / Open
  • 《Adaptive Layer-skipping in Pre-trained LLMs》- 论文笔记
  • 论文阅读:2022 ACL TruthfulQA: Measuring How Models Mimic Human Falsehoods
  • 数据中台(大数据平台)之数据安全管理
  • 4.1.2 Redis协议与异步方式
  • 智造未来:自动化智能检测系统实现近线检测与智能测量协同
  • 技术派|伊朗展示新型弹道导弹,美“萨德”系统真的拦不住?
  • 调节负面情绪可以缓解慢性疼痛
  • “救护车”转运病人半路加价,从宝鸡到西安往返都要多收钱
  • 公元1057年:千年龙虎榜到底有多厉害?
  • “子宫内膜异位症”相关论文男性患者样本超六成?福建省人民医院发布情况说明
  • 国家矿山安全监察局发布《煤矿瓦斯防治能力评估办法》