CSRF 代币 - 如何正确实施?
我刚刚在我的应用程序中设置了一个简单的 CSRF 保护。它创建一个独特的碎屑,在提交表单时根据会话值进行验证。
不幸的是,这意味着现在我无法保持应用程序的多个实例(浏览器中的选项卡)同时打开,因为 CSRF 碎片相互碰撞。
我应该为每个实际表单创建一个单独的令牌,还是为我的所有表单使用相互共享的碎屑? 这里有哪些常识?
I've just setup a simple CSRF protection in my application. It creates a unique crumb which are validated against a session value upon submitting a form.
Unfortunately this means now that I can't keep multiple instances (tabs in the browser) of my application open simultaneously as the CSRF crumbs collide with each other.
Should I create an individual token for each actual form or use a mutual, shared crumb for all my forms?
What are common sense here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你可以做任何一个。这取决于您想要的安全级别。
OWASP Enterprise Security API (ESAPI) 使用每个用户会话使用单个令牌的方法。假设您没有 XSS 漏洞并且会话超时相当短,这可能是一种非常有效的方法。如果您允许会话保持活动数天或数周,那么这不是一个好方法。
就我个人而言,我认为为每个表单的每个实例使用不同的标记并不困难。我使用键值对在用户会话中存储结构。每个项目的键是表单的 ID,值是包含令牌和该令牌的到期日期的另一个结构。通常我只会允许令牌存在 10-20 分钟,然后就会过期。对于较长的表格,我可能会给它较长的有效期。
如果您希望能够在同一会话的多个浏览器选项卡中支持相同的表单,那么我的方法就变得有点棘手,但仍然可以通过拥有唯一的表单 ID 轻松完成。
You can do either. It depends on the level of security you want.
The OWASP Enterprise Security API (ESAPI) uses the single token per user session method. That is probably a pretty effective method assuming you have no XSS holes and you have reasonably short session timeouts. If you allow sessions to stay alive for days or weeks, then this is not a good approach.
Personally, I do not find it difficult to use a different token for each instance of each form. I store a structure in the user's session with key-value pairs. The key for each item is the ID of the form, the value is another structure that contain the token and an expiry date for that token. Typically I will only allow a token to live for 10-20 minutes, then it expires. For longer forms I may give it a long expiry time.
If you want to be able to support the same form in multiple browser tabs in the same session, then my method becomes a little trickery but could still be easily done by having unique form IDs.
OWASP 备忘单对此类问题有最明确的答案事物。它讨论了不同的方法以及安全性与可用性的平衡。
简而言之,他们建议每个(浏览器)会话使用一个令牌。换句话说,在您的情况下,选项卡之间共享相同的令牌。备忘单还强调,不要让您的站点暴露于跨站点脚本漏洞,这一点非常重要,因为这会破坏每个会话的 CSRF 令牌策略。
The OWASP Cheat Sheet has the most definitive answers for this sort of thing. It discusses different approaches and balancing of security vs. usability.
In brief they recommend having a single token per (browser) session. In other words in your case the same token is shared among tabs. The cheat sheet also emphasizes that it is very important not to expose your site to cross site scripting vulnerabilities, as this subverts the per session CSRF token strategy.
据我所知,CSRF,您可以使用
1)随机数并将其保存到会话中:
将其添加到称为隐藏的隐藏输入中,然后当您接收信息时,您可以使用会话值检查隐藏字段
2)静态配置变量(与之前一样,但没有会话)
隐藏字段将包含该值(来自配置的变量)。验证时,您将检查隐藏的发布和配置的安全密钥值
3) HTTP Referer
您可以使用http Referrer 来了解用户来自哪里,然后使用真实域名进行检查(如果您的网站包含xss,此方法可能会受到攻击)。
据我所知,您可以使用任何解决方案:)
As I know about CSRF, you can use
1) Random number and save it into session:
Add it to hidden input called hidden, then when you recive info you can check hidden field with the session value
2) Static config variable (like previous but no session)
The hidden field will contain this value (variable from config). When you validate, you will check the hidden posted and the config security key value
3) HTTP Referer
You can use http referrer to know where user come from then check it with the real domain(this method can attack if your website contain xss).
As I know you can use any solution :)