laravel的csrf为什么不每次请求刷新,yii2的都是每次会变更,公司安全团队指出bug,改怎么解决?

漏洞等级:严重

漏洞详情:

新增、删除、修改等操作均存在CSRF漏洞;以一个接口为例:

1.进入系统设置,菜单管理-修改测试菜单

2.burp抓包,构造CSRF请求包

laravel的csrf为什么不每次请求刷新,yii2的都是每次会变更

3.在浏览器中访问刚刚构造CSRF请求,可成功将排序-8 改成9999

修复建议

  1. 关键页面(新增、修改、删除等)添加csrf token

  2. 校验HTTP头 Referer

所有增删改接口统一修改

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 27
leo

先让你同事重新学一下什么是 CSRF,都能抓包了你用啥 token 都没用

2年前 评论

这不是漏洞,这是feature
CSRF的设计是和Session ID关联的一个凭证,只要Session ID 和 CSRF Token 匹配就可以通过 CSRF 验证。可以看 Laravel 源码哈 GitHub链接

你的安全同事的想法是完全错误的,假如搞成每次刷新都分配一个新 Token,那么旧的页面是否无法提交了呢?如果旧页面新页面都要能够提交,那么每个 Session ID 就要对应一个 CSRF Token 池。本来每个 Session ID 只对应一个 Token, 现在变成一个 Session ID 对应一堆 Token,反而安全性下降了。

如果要让旧的页面无法提交,不应该借助 CSRF 实现该功能,可以业务层自己参考 Google Recaptcha v3 定制一个隐藏验证码的设计,和 CSRF 无关。

另一个问题是,你同事认为可以通过抓包破解 CSRF,是属于用户攻击还是中间人攻击。如果是中间人攻击,上了 https 以后是不可能抓包到 request header 或者 body 数据的;如果是用户攻击,那 CSRF 就更没办法防御了,本质上 CSRF 就是用来保证请求与用户意图一致的。


BTW,你们安全同事对 CSRF PoC generator 的用完全错了,PoC generator 生成出来的页面不应该加上 CSRF Token。

2年前 评论

简单说一下 Laravel 的 CSRF_TOKEN 原理吧,以及为什么不刷新


用户 A 在与服务器建立 SESSION 时,服务器会通过 ASESSION 颁发一个 CSRF_TOKEN,A 在此次登录后所有的请求都通过该 CSRF_TOKEN 来于服务器进行验证身份。

  1. 当发起通信时,除了 GET HEAD OPTIONS 之外,其他类型请求都需要通过 CSRF 验证。
  2. 判断请求路由是否排除在 CSRF 验证之外,如果是,不进行验证
  3. 进行 CSRF_TOKEN 验证

CSRF_TOKEN 颁发相关源码

\vendor\laravel\framework\src\Illuminate\Session\Store.php  // start() 方法

CSRF_Token 验证相关源码

\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php  // handle() 方法

所以即便这个 CSRF_TOKEN 泄露,B 恶意冒充 A 的身份也请求也不会成功,因为 B 无法获取到 A 在服务端的 SESSION,所以没必要每次都刷新 CSRF_TOKEN, 你明白了吗?

2年前 评论
yuwei (楼主) 2年前
MArtian (作者) 2年前

Laravel CSRF 不是一个 token 只能使用一次吗?再用就 419

2年前 评论
yuwei (楼主) 2年前

csrf就是为了一个值只能使用一次。能够刷新的话,就没法防止恶意提交的了

2年前 评论
yuwei (楼主) 2年前

亲,不要透露隐私信息喔,服务地址、同事姓名都算

2年前 评论
╰ゝSakura

亲,不要透露隐私信息喔,服务地址、同事姓名都算

2年前 评论
leo

先让你同事重新学一下什么是 CSRF,都能抓包了你用啥 token 都没用

2年前 评论

csrf中间件里面看一下源码是什么问题罗

2年前 评论
yuwei (楼主) 2年前

请先了解下csrf(跨站请求伪造)是什么再来问问题好吗?

2年前 评论
yuwei (楼主) 2年前

简单说一下 Laravel 的 CSRF_TOKEN 原理吧,以及为什么不刷新


用户 A 在与服务器建立 SESSION 时,服务器会通过 ASESSION 颁发一个 CSRF_TOKEN,A 在此次登录后所有的请求都通过该 CSRF_TOKEN 来于服务器进行验证身份。

  1. 当发起通信时,除了 GET HEAD OPTIONS 之外,其他类型请求都需要通过 CSRF 验证。
  2. 判断请求路由是否排除在 CSRF 验证之外,如果是,不进行验证
  3. 进行 CSRF_TOKEN 验证

CSRF_TOKEN 颁发相关源码

\vendor\laravel\framework\src\Illuminate\Session\Store.php  // start() 方法

CSRF_Token 验证相关源码

\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php  // handle() 方法

所以即便这个 CSRF_TOKEN 泄露,B 恶意冒充 A 的身份也请求也不会成功,因为 B 无法获取到 A 在服务端的 SESSION,所以没必要每次都刷新 CSRF_TOKEN, 你明白了吗?

2年前 评论
yuwei (楼主) 2年前
MArtian (作者) 2年前

$request->session()->regenerateToken()

2年前 评论

盗我头像

2年前 评论

。。。。。。。。建议抽同事大嘴巴子的举个爪~~

2年前 评论
lidongyoo (作者) 2年前
GDDD

你要完全理解csrf,就能有理有据的反驳那群傻逼了。

2年前 评论
yuwei (楼主) 2年前

你们安全团队理解的csrf应该是一个叫做随机令牌的东西,在put,post,delete请求提交的时候要带上服务端生成的这个随机令牌,防止重复提交或防止伪造请求.随机令牌这种用法常见于前后端不分离的架构.

2年前 评论
xiucai (作者) 2年前
yuwei (楼主) 2年前
liziyu 2年前

这不是漏洞,这是feature
CSRF的设计是和Session ID关联的一个凭证,只要Session ID 和 CSRF Token 匹配就可以通过 CSRF 验证。可以看 Laravel 源码哈 GitHub链接

你的安全同事的想法是完全错误的,假如搞成每次刷新都分配一个新 Token,那么旧的页面是否无法提交了呢?如果旧页面新页面都要能够提交,那么每个 Session ID 就要对应一个 CSRF Token 池。本来每个 Session ID 只对应一个 Token, 现在变成一个 Session ID 对应一堆 Token,反而安全性下降了。

如果要让旧的页面无法提交,不应该借助 CSRF 实现该功能,可以业务层自己参考 Google Recaptcha v3 定制一个隐藏验证码的设计,和 CSRF 无关。

另一个问题是,你同事认为可以通过抓包破解 CSRF,是属于用户攻击还是中间人攻击。如果是中间人攻击,上了 https 以后是不可能抓包到 request header 或者 body 数据的;如果是用户攻击,那 CSRF 就更没办法防御了,本质上 CSRF 就是用来保证请求与用户意图一致的。


BTW,你们安全同事对 CSRF PoC generator 的用完全错了,PoC generator 生成出来的页面不应该加上 CSRF Token。

2年前 评论

csrf和jwt有啥区别?

2年前 评论

csrf是用来防止跨站脚本攻击的,不是用来防止重复提交的,是两个概念,虽然都是叫token。。。

11个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!