Grails - 是否有处理 AJAX 形式的 CSRF 攻击的推荐方法? [英] Grails - Is there a recommended way of dealing with CSRF attacks in AJAX forms?
问题描述
我正在将同步器令牌模式用于标准表单(useToken = true),但我找不到任何推荐的通过 AJAX 处理此问题的方法.
I am using the Synchronizer Token Pattern for standard forms (useToken = true) but I cannot find any recommended method of dealing with this over AJAX.
编辑
自从发布这篇文章以来,我已经推出了我自己的解决方案,结合了上面的 Grails 现有模式.
Since posting this, I have rolled my own solution incorporating Grails existing pattern from above.
在 jQuery ajax 中,我发布了整个表单(其中将包括 Grails 注入的 SYNCHRONIZER_TOKEN 和 SYNCHRONIZER_URI 隐藏字段),以便 withForm 闭包可以在控制器中按预期执行.
In the jQuery ajax I post the entire form (which will include Grails' injected SYNCHRONIZER_TOKEN and SYNCHRONIZER_URI hidden fields) such that the withForm closure can perform as expected in the controller.
问题是,在成功响应时,没有设置新的令牌(因为页面没有重新加载并且 g:form taglib 没有被调用),所以我在控制器中手动执行此操作,调用与g:form taglib,在ajax响应中返回,然后重置隐藏字段值.见下文:
The problem is, on successful response, there is no new token set (as the page is not reloaded and the g:form taglib is not evoked) and so I do this manually in the controller calling into the same library as the g:form taglib, and return it in the ajax response, and then reset the hidden field value. See below:
var formData = jQuery("form[name=userform]").serializeArray();
$.ajax({
type: 'POST',
url: 'delete',
data: formData,
success: function (data) {
// do stuff
},
complete: function (data) {
// Reset the token on complete
$("#SYNCHRONIZER_TOKEN").val(data.newToken);
}
})
在控制器中:
def delete(String selectedCommonName) {
def messages = [:]
withForm {
User user = User.findByName(name)
if (user) {
userService.delete(user)
messages.info = message(code: 'user.deleted.text')
} else {
messages.error = message(code: 'user.notdeleted.text')
}
}.invalidToken {
messages.error = message(code: 'no.duplicate.submissions')
}
// Set a new token for CSRF protection
messages.newToken = SynchronizerTokensHolder.store(session).generateToken(params.SYNCHRONIZER_URI)
render messages as JSON
}
谁能确定我是否在不知情的情况下在上述解决方案中引入了安全漏洞.对我来说看起来足够了,但我不喜欢手动滚动任何与安全有关的东西.
Can anyone identify if I have unknowingly introduced a security flaw in the above solution. It looks adequate to me but I don't like hand rolling anything to do with security.
推荐答案
不错!
IMO,你最好同时重置令牌.
IMO, you'd better reset the token at the same time.
SynchronizerTokensHolder.store(session).resetToken(params.SYNCHRONIZER_URI)
如果您在同一页面中有多个表单,请定义一个变量来保存每个 ajax 请求返回的令牌.
and if you have multiple forms in the same page, define a variable to hold tokens returned from each ajax request.
顺便说一句,为什么不自己实现令牌模式?
btw, why not implement the token pattern on your own?
- 生成一个令牌,例如,
UUID.randomUUID().toString()
,并将其存储到以 url 为密钥的会话中. - 在 post 操作的 satrt 处检查并重置令牌.
- Generate a token, e.g.,
UUID.randomUUID().toString()
, and store it into session with the url as the key. - Check and reset the token at the satrt of post actions.
这篇关于Grails - 是否有处理 AJAX 形式的 CSRF 攻击的推荐方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!