我可以使用 JavaScript 在客户端上生成双 cookie CSRF 令牌吗?

信息安全 Web应用程序 javascript csrf
2021-08-22 00:35:33

在提交表单之前使用 JavaScript 创建 CSRF 令牌是否有任何问题?例子:

var csrf_token = Math.random();

// Write csrf token to cookie.

// Add csrf token to the form being submitted.

// Submit form.

// Verify cookie csrf to form csrf on the server.

// When request is done; remove the cookie.

// Rinse and repeat.

我知道这很容易受到 XSS 的攻击,但 XSS 可以只提交带有自定义值的表单,因此 XSS 更糟糕。

1个回答

我不会推荐这个。要使令牌提供任何保护,它必须是不可预测的。Math.random()不是加密安全的——不能保证攻击者不能生成大量随机值,检测模式,然后推断以前的值,从而找到秘密令牌的值。这称为“跨域Math.random()预测”,您可以在此处此处阅读更多相关信息。

我认为(虽然不确定)大多数现代浏览器在实践中都可以防止这种情况发生,但这是一个实现细节,我不会将我的应用程序的安全性押在上面。实际上,MDN 对此提出了警告

Math.random()不提供加密安全的随机数。不要将它们用于与安全相关的任何事情。改用 Web Crypto API,更准确地说是该window.crypto.getRandomValues()方法。

那你可以切换到getRandomValues()吗?仅当您对80% 的浏览器支持感到满意时。

在这样做之前,问问自己为什么不能只在服务器上生成令牌。如果你还是选择客户端方法,至少要避免这两个陷阱:

  • 确保表单中没有令牌,cookie 中没有令牌不通过!一个简单的相等检查可以让它通过,因为两者都是一个空字符串,但这会打开一个漏洞。
  • 必须没有加载页面并自动提交表单的 URL,在此过程中添加令牌。这样的 URL 可能会被滥用。