查看导致我的 CSRF 令牌发生变化的源代码

View Source Code causing change in my CSRF Token

我有一个登录表单,我在其中使用了一个隐藏字段,我正在设置具有随机值的会话以避免 CSRF 攻击,就像这样

<input type="hidden" name="valid" value="<?= $_SESSION['validation'] ?>">

这就是我设置 $_SESSION['validation']

的方式
$_SESSION['validation'] = Hash::create('md5', rand(30, 3000), HASH_KEY);

当用户登录时,它会检查

if ($_SESSION['validation'] == $_POST['valid']) {
 //login
} else {
// Invalid Request
}

所以当用户点击登录页面上的提交按钮时,$_SESSION['validation'] 的值将被比较以进行额外的安全检查。现在的问题是,如果打开登录页面,然后打开查看源代码页面,然后返回登录页面并点击登录按钮。

我面临 "Invalid Request" 因为打开查看源代码页面会更改 $_SESSION['validation'] 值,而我们之前打开的登录页面在表单中具有旧的 $_SESSION['validation'] 值作为隐藏值.如何应对?

同样适用于验证码的情况。所以最终用户不会查看源代码。验证将正常进行。

如果您仍想生成相同的令牌,那么在生成新令牌时请遵循以下步骤:

// Create a new CSRF token.
if (! isset($_SESSION['validation'])) {
    $_SESSION['validation'] = Hash::create('md5', rand(30, 3000), HASH_KEY);
}

//once validation is complete / successfully / failed then generate a new token
 if ($_SESSION['validation'] == $_POST['valid']) {
      $_SESSION['validation'] = Hash::create('md5', rand(30, 3000), HASH_KEY);
       //process the form data
  }

参考:https://gist.github.com/ziadoz/3454607

问题在于,在某些浏览器和情况下,查看源代码会导致浏览器请求页面的新副本,而不是向您显示它已有的副本。如果您在不同的选项卡中打开站点的两个页面,则会出现同样的问题,这对于您的实际最终用户来说更有可能出现。

CSRF 令牌抵御的主要攻击是 link 或用户根本未加载的表单,而不是很久以前加载的表单,因此您可以通过以下方式改进在会话中保留最近令牌的列表,而不仅仅是最近的。您可以将到期时间与每个令牌相关联,这样保存的页面就不能在数小时后使用,这也有助于避免用户提交基于过时数据的内容的问题。您不希望同一个令牌被接受两次,因此请记住在使用时将其从列表中删除。

不过,在某些高度安全的情况下,您可能希望严格并避免任何深度linking、back/forward 导航或选项卡式浏览,因此当前行为将是您想要的想。许多在线银行应用程序都这样做,例如,如果用户导航 "in the wrong order",则强制用户重新登录,因此有人在关闭 window 并继续会话后无法来到计算机前.