TL;DR: 是的,您或您使用的框架都需要有服务器端逻辑来验证 CSRF 令牌。它不能是 cookie,它必须是要求用户在您的页面上的东西,而不是点击攻击者提供的链接。
您的工作流程非常正确。第一步是生成一个攻击者无法预测的加密随机字符串。每种编程语言都有自己的结构来执行此操作,但是 24 - 32 个字符的字符串应该可以很好地达到此目的。
在我们进入下一步之前,让我们确保我们知道我们正在处理什么威胁 - 我们不希望攻击者代表用户发出请求,所以应该有一些东西可以访问要求用户执行操作以发送令牌的浏览器,但是,如果用户单击攻击者设置的内容,则不应发送令牌。
鉴于此,不应该这样做的一种方法是使用 cookie。每次向设置 cookie 的域发出请求时,浏览器都会自动发送 cookie,因此这会自动破坏我们的防御。
也就是说,让我们进入下一步,即以一种您可以在服务器端验证但攻击者无法访问的方式设置此令牌。有多种方法可以做到这一点:
1) A CSRF 标头:这在许多 node.js/Express 安装中完成 - CSRF 令牌作为标头发送,具体而言,是 X-CSRF-Token 标头。生成此令牌后,服务器将其存储在该特定 cookie 的会话存储中。在前端,令牌存储为 JavaScript 变量,这意味着只有在该特定页面上生成的请求才能具有标头。每当发出请求时,会话 cookie(在 node.js 的情况下,连接。 sid) 并且所有 POST/PUT/DELETE 请求都需要 X-CSRF-Token。如果发送了错误的令牌,服务器会发送 401 Unauthorized,并重新生成令牌,请求用户登录。
<script type="text/javascript">
window.NODE_ENV = {};
window.NODE_ENV.csrf = "q8t4gLkMFSxFupWO7vqkXXqD";
window.NODE_ENV.isDevelopment = "true";
</script>
2) 隐藏的表单值:很多 PHP 安装使用它作为 CSRF 防御机制。根据配置,特定于会话或特定于请求(后者是多余的,除非应用程序需要它)令牌嵌入在隐藏的表单字段中。这样,每次提交表单时都会发送它。验证方法各不相同 - 可以通过针对数据库进行验证,也可以是特定于服务器的会话存储。
3) Double Submit Cookies:这是 OWASP 建议的一种机制,除了通过标头发送会话 cookie 之外,您还可以将其包含在提交的表单中。这样,一旦您验证会话有效,您就可以验证表单是否也包含会话变量。如果你使用这种机制,确保在验证 CSRF 之前验证用户的会话是至关重要的;否则,它会引入缺陷。
在构建/测试此机制时,请务必注意,尽管许多实现将其限制为 POST/DELETE/PUT 事务,这是因为它自动假定所有敏感事务都通过此动词发生。如果您的应用程序使用 GET 执行敏感事务(例如激活),那么您也需要此机制用于 GET/HEAD。