实现跨域CSRF保护



我知道这个问题已经被问过好几次了,但我从来没有找到一个明确的解决方案。如何保护web应用程序免受CSRF攻击?

我目前有两个域,frontend.combackend.com。后端使用flask-wtf创建会话(存储在前端浏览器的cookie中),并在响应头中返回CSRF token

我能够获得令牌,并发送带有令牌附加到报头的请求。然而,我注意到饼干从来没有凝固过。因此,我假设这就是为什么我得到一个错误的400: Bad Request。经过不断的阅读和研究,我几乎确信它意味着在相同的域中使用。.

我目前的技术栈是:

DNS: Cloudflare

托管:Heroku

  • 反应客户
  • Python (Flask) API

我看不出CSRF令牌如何在这种情况下使用,除非我错过了对它工作至关重要的东西。

也就是说,根据我的情况,在跨域设置中解决CSRF保护的最佳方法是什么?

此外,这一切都在我的本地开发环境中工作。我不知道为什么它在生产中突然停止工作了。

一个示例请求看起来像这样:

const headers = {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken 
};
...
const handleFormSubmission = async e => {
e.preventDefault();
await axios.post('https://backend.com/add-results', { tokenId: tokenId }, { withCredentials: true, headers: headers })
}

后端有以下设置:

...
CORS(app, origins=["https://www.frontend.com"], expose_headers=["Content-Type", "X-CSRFToken"], supports_credentials=True)  
...
app.config['SESSION_COOKIE_SECURE'] = True
app.config['SESSION_COOKIE_HTTPONLY'] = True
app.config['REMEMBER_COOKIE_SECURE'] = True
app.config['REMEMBER_COOKIE_HTTPONLY'] = True
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'

这是非常奇怪的,因为这工作在开发环境

您实际上似乎有一个工作CSRF保护到位。你说:

我能够获得令牌并发送带有令牌附加到报头的请求。然而,我注意到饼干从来没有设置过。

所以你的问题似乎是你没有得到会话cookie,这是另一回事。

这是跨域请求的典型问题。默认情况下,由于安全原因,浏览器不会将cookie发送到另一个域。您要么需要通过Access-Control-*头启用CORS,要么使用替代令牌存储机制而不是cookie(例如Web storage)。

我非常推荐Api Security in Action这本书,它在第5章讨论了这个主题(特别是5.1和5.2的Web存储)

相关内容

  • 没有找到相关文章

最新更新