Grails - 是否有推荐的方式来处理AJAX表单中的CSRF攻击? [英] Grails - Is there a recommended way of dealing with CSRF attacks in AJAX forms?

查看:127
本文介绍了Grails - 是否有推荐的方式来处理AJAX表单中的CSRF攻击?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用标准形式的Synchronizer Token Pattern(useToken = true),但是我找不到任何推荐的方法来处理这个AJAX问题。



编辑



自从发布这篇文章以来,我已经推出了自己的解决方案,将上面的Grails现有模式整合在一起。

在jQuery ajax中,我发布了整个表单(包括Grails注入的SYNCHRONIZER_TOKEN和SYNCHRONIZER_URI隐藏字段),以便withForm闭包可以在控制器中按预期执行。



问题是,在成功响应时,没有新的标记集(因为页面没有重新加载,并且没有激发g:form标签库),所以我在控制器中手动执行这个操作,调用与g相同的库:形成taglib,并在ajax响应中返回它,然后重置隐藏的字段值。
见下:

  var formData = jQuery(form [name = userform])。serializeArray(); 

$ .ajax({
type:'POST',
url:'delete',
data:formData,
success:function(data ){
// do stuff
},
complete:function(data){
//重置完整
$(#SYNCHRONIZER_TOKEN)上的令牌。 val(data.newToken);
}
})



  def delete(String selectedCommonName){

def messages = [:]
withForm {
user user = user.findByName(name)
$ b $ 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')
}
//为CSRF保护设置一个新标记
messages.n ewToken = SynchronizerTokensHolder.store(session).generateToken(params.SYNCHRONIZER_URI)
将消息呈现为JSON
}

任何人都可以确定我是否在不知不觉中在上述解决方案中引入了安全漏洞。它看起来对我来说是足够的,但我不喜欢手滚动任何与安全有关的事情。



IMO,您最好同时重置令牌。

SynchronizerTokensHolder.store session).resetToken(params.SYNCHRONIZER_URI)



如果在同一页面中有多个表单,定义一个变量来存放从每个ajax请求。

btw,为什么不自己实现标记模式?


  • 生成一个标记,例如 UUID.randomUUID()。toString(),并将其存储到以url作为关键字的会话中。

  • 检查并重置帖子操作中的令牌。


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.

EDIT

Since posting this, I have rolled my own solution incorporating Grails existing pattern from above.

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.

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);
    }
})

in the Controller:

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.

解决方案

Nice!

IMO, you'd better reset the token at the same time.

SynchronizerTokensHolder.store(session).resetToken(params.SYNCHRONIZER_URI)

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?

  • 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆