首页 > 解决方案 > 从外部链接链接时基于会话的 CSRF 令牌

问题描述

我在外部链接页面上遇到了 CSRF 令牌问题。

我在 whatsapp 中有一个聊天机器人,可以向用户发送一个指向该网站的一次性链接。他们单击链接并需要在网站上输入 PIN 以确认请求(我们这样做是为了让用户的 PIN 永远不会以纯文本形式保存在 whatsapp 上)。

与网站上的所有表单一样,PIN 页面也有一个隐藏的 CSRF 令牌,该令牌也会被提交。CSRF 令牌部分与会话 id 一起生成,并且在提交时验证的一部分是检查其当前会话。

我看到一个问题,在某些提交的 PIN 页面上,由于会话 ID 与初始页面加载请求不同,CSRF 验证失败。

我对正在发生的事情的猜测是用户已经与该站点进行了活动会话(让我们称之为session 001)。他们稍后会收到他们点击的whatsapp链接。看起来有时浏览器不会发送现有的会话 cookie(我假设是由于SameSite政策方面的一些收紧),所以当用户登陆 PIN 页面时,网站将其视为新访问并创建一个新的session 002. 然后在提交表单时,浏览器会发送原始的“session 001”cookie。因此,令牌 CSRF 令牌是使用“会话 002”生成的,但针对session 002. (可能值得注意的是,这是一个遗留系统,没有明确设置 SameSite 策略)

我不想在生产中记录会话 ID,所以我想不出一种方法来验证这实际上是发生了什么。我还不能在我的开发环境中复制这种行为。

这听起来像是我不太了解的已知事情吗?有关解决此问题的方法的任何想法?

标签: phpsessionsession-cookiescsrfcsrf-token

解决方案


会话在作为概念模型 (IMO) https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage的浏览器选项卡重新加载之间不起作用。在您的用例中,会话是在浏览器选项卡重新加载之间(通过刷新、硬刷新或通过外部链接导航),除非通过“返回”按钮按下重新加载。所以简而言之,您需要自己的会话 UUID 生成器和管理器。尝试使用在大多数 Web 服务器平台中实现的 UUID 类。

由于 http 的规定,localhost 的工作方式可能有所不同,尽管我无法弄清楚为什么这在 localhost 中无法重现。


推荐阅读