回顾CSRF (Cross Site Request Forgery)

之前项目中遇到了SameSite的使用, SameSite主要解决CSRF (Cross Site Request Forgery)问题,顺便也回顾下CSRF吧。

一、原理

利用被攻击网站服务器用户网页浏览器的信任。

  1. 用户对合法网站的认证cookie(登录态等)会保存在浏览器端;
  2. 跨站请求时浏览器会携带相关cookie的;

当用户浏览恶意网页时,攻击者通过一些技术手段欺骗用户的浏览器去访问一个用户曾经认证过的网站并运行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。因为请求也是携带认证cookie信息的,服务端没有合适的防御措施的话就很难识别请求是用户正常请求还是CSRF请求。

1.1 特点:

结合原理和CSRF命名可以看出CSRF的特点:

  1. Cross Site: 攻击方在第三方站点;
  2. Request Forgery: 当用户浏览恶意站点时向被攻击的服务器发送操作请求。

攻击者不要获取用户的信息(cookie等),直接欺骗用户的浏览器,让其以用户的名义运行操。

二、攻击手段

直接引入前端安全系列之二:如何防止CSRF攻击?的DEMO:

受害者登录a.com,并保留了登录凭证(Cookie)。
攻击者引诱受害者访问了b.com。
b.com 向 a.com 发送了一个请求:a.com/act=xx。浏览器会默认携带a.com的Cookie。
a.com接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求。
a.com以受害者的名义执行了act=xx。
攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让a.com执行了自己定义的操作。

三、防御

针对CSRF的攻击原理,制定防御策略:

  1. 攻击来自第三方站点:

    • sameSite cookie:告诉浏览器禁止跨站请求携带cookie;
    • 同源检测(验证HTTP Referer字段):服务器增强校验。
  2. 伪造请求
    生成无法伪造的数据,服务器增强校验,识别伪造请求。

3.1 验证HTTP Referer字段

方案

[[科普]跨站请求伪造-CSRF防护方法](https://www.freebuf.com/artic...

缺点

  1. 虽然在CSRF攻击中,Referer是无法伪造的,但是维护比较困难;
  2. Referer配置不准确的话,很容易阻断正常请求;
  3. 后期维护困难,随着url的变化需不断修改Referer

总之不推荐使用

3.2 在请求地址中添加token并验证

方案

[[科普]跨站请求伪造-CSRF防护方法](https://www.freebuf.com/artic...
利用token标记合法请求。

CSRF token的生成,下发,上送,校验

1. 生成
  1. 由服务端生成随机唯一的字符串(GUID, UUID等),并保存到服务端的session或者其他服务端缓存(如Redis);

    • token的缓存最好有过期时间;
  2. 如果希望提高token的安全性可以对生成的token进行对称加密
2. 下发

下发是服务端如何把生成的CSRF token传给客户端,方式很多了,看客户端怎么方便提取并传给后端。

  1. 千万别千万别千万别通过Set-Cookie下发;
  2. 喷到页面里作为约定的全局变量;
  3. 最好和后端一起确定一个标准的下发和上送方式。
3. 上送

上送:是客户端调用接口时提取CSRF token并传给服务。看请求接口类型也后很多上送方式。

  1. 针对GET请求可以放入queryString里;
  2. Form POST请求可以添加隐藏域;
  3. AJAX, fetch请求还可以采用放入request header里;
  4. 最好和后端一起确定一个标准的上送方式。
4. 校验
  1. 服务端从请求里获取客户端上送的token
  2. 解密(如果之前有加密的话);
  3. 再跟缓存(Session/Redis)的值对比。

四、哪些场景需要考虑CSFR

重要的场景都需要并且建议采用token方案,一些常见的case有:

  1. 支付类场景(支付,转账,充值);
  2. 取消/关注好友,转发,删除(日志,帖子等),发邮件等操作;
  3. 信息更改类(更改手机号,邮箱等)。

参考:

整理自GitHub笔记:CSRF

Coder

2.6k 声望
52 粉丝
0 条评论
推荐阅读
解析position: sticky;
粘性定位position sticky元素采用正常的文档流布局(static),当其边框(border矩形)相对于最近的滚动祖先元素的内边框(即content矩形)的小于指定阈值时,则position sticky元素相对于该最近的滚动祖先元素固...

普拉斯强3阅读 2.7k评论 1

安全地在前后端之间传输数据 - 「3」真的安全吗?
在「2」注册和登录示例中,我们通过非对称加密算法实现了浏览器和 Web 服务器之间的安全传输。看起来一切都很美好,但是危险就在哪里,有些人发现了,有些人嗅到了,更多人却浑然不知。就像是给门上了把好锁,还...

边城31阅读 7.2k评论 5

封面图
涨姿势了,有意思的气泡 Loading 效果
今日,群友提问,如何实现这么一个 Loading 效果:这个确实有点意思,但是这是 CSS 能够完成的?没错,这个效果中的核心气泡效果,其实借助 CSS 中的滤镜,能够比较轻松的实现,就是所需的元素可能多点。参考我们...

chokcoco20阅读 2.1k评论 2

在前端使用 JS 进行分类汇总
最近遇到一些同学在问 JS 中进行数据统计的问题。虽然数据统计一般会在数据库中进行,但是后端遇到需要使用程序来进行统计的情况也非常多。.NET 就为了对内存数据和数据库数据进行统一地数据处理,发明了 LINQ (L...

边城17阅读 1.9k

封面图
【已结束】SegmentFault 思否写作挑战赛!
SegmentFault 思否写作挑战赛 是思否社区新上线的系列社区活动在 2 月 8 日 正式面向社区所有用户开启;挑战赛中包含多个可供作者选择的热门技术方向,根据挑战难度分为多个等级,快来参与挑战,向更好的自己前进!

SegmentFault思否20阅读 5.6k评论 10

封面图
过滤/筛选树节点
又是树,是我跟树杠上了吗?—— 不,是树的问题太多了!🔗 相关文章推荐:使用递归遍历并转换树形数据(以 TypeScript 为例)从列表生成树 (JavaScript/TypeScript) 过滤和筛选是一个意思,都是 filter。对于列表来...

边城18阅读 7.7k评论 3

封面图
你可能不需要JS!CSS实现一个计时器
CSS现在可不仅仅只是改一个颜色这么简单,还可以做很多交互,比如做一个功能齐全的计时器?样式上并不复杂,主要是几个交互的地方数字时钟的变化开始、暂停操作重置操作如何仅使用 CSS 来实现这样的功能呢?一起...

XboxYan21阅读 1.6k评论 1

封面图

Coder

2.6k 声望
52 粉丝
宣传栏