之前项目中遇到了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


普拉斯强
2.7k 声望53 粉丝

Coder