使用 Express API 和 React 前端防止 CSRF

Preventing CSRF with an Express API and a React frontend

过去几天我一直在阅读有关 CSRF 的文章,感觉我已经很好地掌握了它是什么以及如何预防它。我正在构建一个小型 Express/React 应用程序,它将有一个用于更新应用程序内容的安全管理区域,我希望它免受 CSRF 攻击。

据我所知,服务器生成 CSRF 令牌然后将其与已请求的视图(页面)一起发送给客户端是很常见的(然后令牌可以隐藏在 HTML 表单输入标签)。但是,我的 Express API 不提供 HTML,它是一个 REST API,只有 returns JSON 数据。 UI 是用 React 构建的,运行 在与服务器不同的端口上。

我的问题是;我在哪里安全地存储在服务器上生成的令牌?

例如,如果我通过点击“/api/login”以管理员身份登录,生成一个令牌,并在 API 响应中将其发送回客户端,我应该如何处理它现在?

最初的计划是使用 Redux 来存储令牌,但是从阅读这篇文章 post Is Redux secure?,这听起来并不理想。

我考虑过使用 React env 变量,但也了解到这些在构建中公开了。

显然 localStorage 也是一个坏主意...

我真的很难使用我正在实施的工具找到解决这个问题的方法,即 Express/React

如有任何帮助、链接、建议、批评,我将不胜感激,我想学习在构建应用程序时考虑到安全性

I understand that it is common for the server to generate the CSRF token

服务器需要生成两个CSRF令牌

and then send it to the client along with the view (page) that has been requested (the token can then be hidden in a HTML form input tag).

一个令牌通常作为 cookie 发送,另一个可以作为 HTTP header 发送。它不需要作为 HTML 表单输入标签(或 body 的任何其他部分)在 HTML body 内发送,尽管它可以通过这种方式发送。

My question is; Where do I securely store a token generated on the server?

您不必在服务器上存储令牌。你可以,但你不需要。

The original plan was to use Redux to store the token

Redux 存储在客户端,在浏览器的内存中。理论上,一个 React 组件(从服务器响应中提取第二个 CSRF 令牌)可以临时将令牌存储在商店中,以便另一个 React 组件可以从那里获取它并在将其发送到服务器之前放入下一个请求。

Obviously localStorage is also a bad idea...

Any help, links, advice, criticisms would be appreciate, I want to learn to build apps with security in mind

链接
With Express 很常用this middleware. The steps can be found here.

批评
在 CSRF 相关 Q/A 的上下文中,这严格来说是题外话,但是 ...

The UI is built with React, running on a different port from the server.

这暗示了使用从 webpack-dev-server 开始的 react-scripts 的可能性。它适合开发,不适合在生产中部署。然而,这是一个单独的主题,为 Web 客户端提供 React 应用程序的构建工件(.html 文件、脚本包)与 CSRF 攻击及其缓解措施无关。

I want to learn to build apps with security in mind

那么您可以考虑使用一个网络服务器而不是两个(前端服务于 React 应用程序,后端服务于 API 响应)。使用一台服务器导致生产部署不仅不那么复杂和昂贵,而且更安全,因为两台服务器具有更大的攻击面,而对于一台服务器,您不需要通过使用 CORS 来削弱安全性。