简体   繁体   English

如何在 Symfony 2 中跨多种表单实现单个 CSRF 令牌?

[英]How can I achieve a single CSRF token across multiple forms in Symfony 2?

... and should I even be attempting this? ......我什至应该尝试这个吗?

I'm using Symfony 2 (just upgraded from 2.3 to 2.5 ) and from my experience the framework leans towards generating a CSRF token per form.我正在使用 Symfony 2(刚刚从2.3升级到2.5 )并且根据我的经验,该框架倾向于为每个表单生成一个CSRF令牌。 This is fine if you have one form per page, but often times you want to have multiple forms on a page, hidden, with one form presenting itself after a user interaction of some kind.如果您每页有一个表单,这很好,但通常您希望在一个页面上有多个表单,隐藏,在某种用户交互后显示一个表单。

In Java, using the Spring Framework, the CSRF token appears to be associated with the session (and supplied as an attribute on the request).在 Java 中,使用 Spring 框架, CSRF令牌似乎与会话相关联(并作为请求的属性提供)。

My two use cases are: (1) supporting multiple forms (of the same type) on the same page using JavaScript driven templates (eg Handlebars ) and (2) having multiple forms (of different types) on the same page also driven by JavaScript templates.我的两个用例是: (1)使用 JavaScript 驱动的模板(例如Handlebars )在同一页面上支持多个表单(相同类型)和(2)在同一页面上有多个表单(不同类型)也由 JavaScript 驱动模板。

My question is threefold:我的问题有三个:

  1. Is there any way to achieve a CSRF -token per session rather than per form intention?有什么方法可以实现每个会话的CSRF令牌而不是每个表单意图? What are the arguments against this?对此有何反对意见?
  2. Can this be achieved "out-of-the-box" or would a custom provider need to be written which ignores the intention of a form?这可以“开箱即用”实现,还是需要编写忽略表单intention的自定义提供程序?
  3. Would it be better to serialize the form-type(s) to JSON and maintain the different instances of the CSRF token per form?将表单类型序列化为JSON并维护每个表单的CSRF令牌的不同实例会更好吗?

As an aside, OWASP presents a general recommnedation on this subject: 顺便说一句,OWASP 提出了关于这个主题的一般建议

" In general, developers need only generate this token once for the current session. After initial generation of this token, the value is stored in the session and is utilized for each subsequent request until the session expires. When a request is issued by the end-user, the server-side component must verify the existence and validity of the token in the request as compared to the token found in the session... " "一般情况下,开发者只需要为当前会话生成一次这个token。这个token初始生成后,这个值会保存在session中,用于后续的每次请求,直到session过期。当请求结束时-user,服务器端组件必须验证请求中令牌的存在和有效性,与会话中找到的令牌相比......

1) csrf tokens are generated per form per session, so if you want to have a csrf token per session you just need to make sure the intention (which is the name of the form by default) is the same for all forms. 1) csrf 令牌是针对每个会话的每个表单生成的,因此如果您希望每个会话都有一个 csrf 令牌,您只需要确保所有表单的意图(默认情况下是表单的名称)都相同。 the problem is that you'll basically open the gates for people to submit one form in place of another as when the form is validated, it will check the csrf and validate as true even though that from is not the one it was looking for.问题是,您基本上会为人们打开大门,让他们提交一个表单来代替另一个表单,因为当表单被验证时,它会检查 csrf 并验证为真,即使该表单不是它正在寻找的那个。

2) you just really need to make sure you set the intention yourself when you create and validate a form 2)您只需要确保在创建和验证表单时自己设置意图

3)The best way to achieve what you want is to just render each form and use javascript to serialize and submit the forms to separate controller actions. 3)实现您想要的最佳方法是渲染每个表单并使用javascript序列化并将表单提交给单独的控制器操作。 your code will be much cleaner and you'll have fewer security issues.您的代码会更简洁,安全问题也会更少。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM