当前位置:网站首页>关于CSRF及其防御
关于CSRF及其防御
2022-06-09 10:47:00 【Johnny丶me】
关于CSRF
- CSRF(Cross Site Request Forgy) 跨站请求伪造
- 在用户不知情的情况下,其他网站对目标网站发出请求
- 举个例子,比如你通过一个链接的点入,在其他网站上发表了一条动态
- 也就是身份的盗用,这是一件非常可怕的事情
- CSRF有个别称叫做"一点就爆炸",甚至,不需要点击,比如刷新一下
- 只要能够产生请求就会存在CSRF攻击的可能
- CSRF的攻击可以是多种多样的
- 可以是表单,链接和图片等多种形式
- 一次刷新,一个点击即可触发
- 可以通过GET和POST的请求,而GET请求更致命,传播性更广
- 一般CSRF可以称得上是一种网络蠕虫,传染性很强
- 举个具体的代码示例
// 创建一个表单 document.write(` <form name="commentForm" target="csrf" method="post" action="目标网站的某一个接口地址"> <input name="postId" type="hidden" value="1"> <textarea name="content">来自CSRF!</textarea> </form>` ); // 创建一个iframe var iframe = document.createElement('iframe'); iframe.name = 'csrf'; iframe.style.display = 'none'; // 隐藏状态 document.body.appendChild(iframe); // 页面加载完成后提交表单 setTimeout(function(){ // 表单的target是iframe,会在iframe内进行提交和跳转, 当前页面没有任何变化 document.querySelector('[name=commentForm]').submit(); }, 1000);
CSRF攻击的原理
- 主要涉及两个网站,一个是目标网站,一个是攻击者网站
- 用户在目标网站进行登录,会有登录态session和一些凭证信息如cookies
- 攻击者会通过一些手段, 比如链接,图片等方式利用用户在目标网站的身份, 向目标网站发送数据
- 注意此时绕过了目标网站的前端,直接请求了目标网站的接口,举个具体的例子:
- 用户只要在一个浏览器下登录过目标网站A,就会在A网站下存入身份标识,如cookie
- 如果攻击者通过一封邮件,让用户点击邮件中的某个链接,此时这个链接打开了同样的浏览器
- 该链接是A网站的某个接口,同时附带一些攻击者想要提交的数据
- 因为用户登录过A网站,此时只要一点击这个链接就会自动发送攻击者想要提交的数据
CSRF攻击的危害
- 用户完全不知情的情况下,利用用户登录态
- 完成业务请求,如盗取用户资金(转账,消费)
- 再比如,冒充用户发帖,用户背锅,这是直接危害
- 同样间接地损害目标网站的声誉
CSRF攻击案例
- QQ购买道具接口存在漏洞,导致道具连续购买,用户钱财不断被消耗
- QQ音乐分享到腾讯微博歌单,发送一条带有蠕虫的微博消息,不断被传播
- 当然,这些漏洞已经被修复了,我们应该警醒类似案例
CSRF如何防御
- 通过CSRF攻击的原理知道访问目标网站时的referer为攻击者网站
- 我们可以通过这个特征来做防御,一般而言,我们可以这样
- 1 ) 在目标网站设置cookie时添加same-site属性
- SameSite属性有两个值:Strict, Lax
- Strict表示最为严格,完全禁止第三方Cookie,跨站点时,任何情况下都不会发送Cookie
- Lax表示大多数情况也是不发送第三方Cookie,但是导航到目标网址的Get请求除外
- 设置了Strict或Lax以后,基本就杜绝了CSRF攻击,当然,前提是用户浏览器支持SameSite属性
- 网站可以选择显式关闭SameSite属性,将其设为None
- 不过,前提是必须同时设置Secure属性(Cookie只能通过HTTPS协议发送), 否则无效
- 但是SameSite属性兼容性并不是很乐观,所以并非普适地解决CSRF攻击
- 在koajs中设置SameSite示例
ctx.cookies.set('userId', user.id, { sameSite: 'strict'})
- 2 ) 在目标网站进行referer的过滤,只允许合法请求
- 在哪里发起请求,referer就是谁,比如从A跳转到B,那么B的referer就是A
- 如果referer是合法的地址,我们就通过,不合法我们就拒绝
- 可以自定义合法referer列表,代码上也很好实现,做个严谨的判断即可
- 注意, 如果是file协议访问是获取不到referer的,要通过http协议的形式才会有referer
- 3 ) 在目标网站前端加入验证信息:验证码
- 每次提交必须要有验证码,并且验证码相等
- 在nodejs中关于生成图形验证码的没有原生的方法可以参考ccap的库
- 这时候就可以有效阻碍CSRF攻击了,但是不可能所有的表单请求都要去做验证码校验
- 通过验证码可以防御,但生产环境下使用并不理想,体验很差,代码就不作举例,比较麻烦
- 4 ) 在目标网站前端加入验证信息:token
- 让攻击者发起请求后无法直接获取,必须要经过网站前端
- 后端生成一个csrftoken, 也就是一个随机字符串
- 一个放在页面的表单中,一个放在cookies中
- 校验cookies中的token和表单中的token是否一致
- 一致表示正确直接放行,不一致说明存在错误或攻击
- Django这个框架就是这么处理CSRF攻击的
- 同样在普通的ajax请求中也可以这么校验,我们可以在页面的meta上存储token
- 在正常发送ajax请求的时候获取token并且发送cookies中的值交给后端校验
- 存在一个问题是多页面下只有最新打开的页面的表单能够提交,因为多个页面上的token不一致,而cookie动态变更
- 解决方法有很多,比如页面token失效,校验不一致,再次请求新的页面token,可以有效的解决问题
- 注意这里我们的两个token:一个是页面上的token,一个是cookies中的token
- 1 ) 在目标网站设置cookie时添加same-site属性
PHP防御CSRF
1 ) PHP中使用samesite这个cookies属性
- PHP中打cookies的方式有两种:
- 可以直接通过setcookie函数, 如
setcookie('test', '123')这里并不支持SameSite属性的设置 - 可以通过header函数来设置cookies, 如
header('Set-Cookie: test=123; SameSite=Lax');
- 可以直接通过setcookie函数, 如
2 ) 根据HTTP referer头
- 获取referer头:
var_dump($_SERVER['HTTP_REFERER']) - 具体用法可以参考
if($_SERVER['HTTP_REFERER']) { // 判断referer是否符合合法域名, 可以有多种实现,可支持定义域名列表,下面只提供一种 $isLegal = strpos($_SERVER['HTTP_REFERER'], 'http://localhost') === 0; var_dump(isLegal); // 将是否输出到页面 }
3 ) 根据token处理
- 可参考代码
$csrfToken = rand(1000,9999); // 定义一个token, 随机数, 当然最好弄成更复杂的, 此处只作举例 setcookie('csrfToken', $csrfToken); // 给站点打上相关cookie if($_POST['csrfToken'] === $_COOKIE['csrfToken']) { // ... 匹配了,处理自己的逻辑 } <form method='post'> <input type='text' name='csrfToken' value="<?php echo $csrfToken;?>"> <textarea name='content'>hello</textarea> <button type='submit'>提交</button> </form>
4 ) 根据验证码处理
- 因为验证码这个方案用户体验并不是很好,在任何语言中处理都应作为最后的方案
- 此处不再推荐
边栏推荐
- This article takes you to understand gaussdb (DWS) [Gauss is not a mathematician this time]
- PerfDog发布全新指标,为游戏量身打造
- 10 useful flutter widgets
- TemplateDoesNotExist at /users/register/
- Analysis on self defined attributes of sub components
- 自己建设网站需要做哪些准备
- [email protected] -808 loaded 5-fluorouracil| [email protected]
- MySQL 学习笔记-第五篇-数据备份与恢复、MySQL 日志
- 一文带你了解GaussDB(DWS) 【这次高斯不是数学家】
- 浅析子组件自定义属性问题
猜你喜欢

Tencent, Shanghai Jiao Tong and Zhejiang University proposed pyramid clip to align the semantic within the hierarchy and cross hierarchy relationship. The zero shot effect is better than clip

文档书写规范

More than observation | Alibaba cloud observable Technology Summit officially launched

无法在debug时进入ArrayList底层解决方案

Cyclodextrin metal organic framework loaded low molecular weight heparin and adriamycin (MOF metal organic framework loaded biological macromolecular drugs)

数据资产管理:企业的数据资产怎么盘?

idea取消数据简化

Tidb cloud launched Google cloud marketplace, empowering global developers with a new stack of real-time HTAP databases

Multi engine database management tool DataGrid 2022.1.5 Chinese version

Baidu post-90s programmers were sentenced for deleting and modifying databases, saying they were dissatisfied with their leaders
随机推荐
Daily question -1232 Dotted line
(critical) chassis-frontend.c:122: Failed to get log directory, please set by --log-path
[buuctf.reverse] 115_[RCTF2019]DontEatMe
Leetcode 159 Longest substring containing at most two different characters (2022.06.08)
One question per day -1200 Minimum absolute difference
Network wide detailed interface test apipost detailed tutorial (actual combat), hematemesis sorting
执行引擎-(编译器、JIT)
redis中数据结构的学习笔记
Music creation tool Steinberg Cubase Pro
Tidb cloud launched Google cloud marketplace, empowering global developers with a new stack of real-time HTAP databases
对象的实例化和访问
全网详细接口测试ApiPost详细教程(实战),吐血整理
第三章运输层
Object instantiation and access
RDMA Verbs API
flutter 弹窗flutter_easyloading
Course design of network sniffer design based on C language
Flink CDC + Hudi 海量数据入湖在顺丰的实践
php redis 常用操作手册
P5482 [jloi2011] inequality system, cckk