这不是漏洞,这是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。
简单说一下 Laravel 的 CSRF_TOKEN 原理吧,以及为什么不刷新
用户 A 在与服务器建立 SESSION
时,服务器会通过 A
的 SESSION 颁发一个 CSRF_TOKEN,A 在此次登录后所有的请求都通过该 CSRF_TOKEN
来于服务器进行验证身份。
- 当发起通信时,除了
GET
HEAD
OPTIONS
之外,其他类型请求都需要通过CSRF
验证。 - 判断请求路由是否排除在
CSRF
验证之外,如果是,不进行验证 - 进行
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
, 你明白了吗?
简单说一下 Laravel 的 CSRF_TOKEN 原理吧,以及为什么不刷新
用户 A 在与服务器建立 SESSION
时,服务器会通过 A
的 SESSION 颁发一个 CSRF_TOKEN,A 在此次登录后所有的请求都通过该 CSRF_TOKEN
来于服务器进行验证身份。
- 当发起通信时,除了
GET
HEAD
OPTIONS
之外,其他类型请求都需要通过CSRF
验证。 - 判断请求路由是否排除在
CSRF
验证之外,如果是,不进行验证 - 进行
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
, 你明白了吗?
这不是漏洞,这是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。
推荐文章: