Security Grails-有没有推荐的方法来处理AJAX表单中的CSRF攻击?
我正在为标准表单使用同步器令牌模式(useToken=true),但是我找不到任何推荐的方法通过AJAX来处理这个问题 编辑 自从发布这篇文章以来,我已经推出了自己的解决方案,其中包含了上面的Grails现有模式 在jqueryajax中,我发布了整个表单(其中包括Grails注入的SYNCHRONIZER\u令牌和SYNCHRONIZER\u URI隐藏字段),以便withForm闭包可以在控制器中按预期执行 问题是,在成功响应时,没有新的令牌集(因为页面没有重新加载,g:form标记库也没有被调用),因此我在控制器中手动执行此操作,调用与g:form标记库相同的库,并在ajax响应中返回它,然后重置隐藏字段值。 见下文:Security Grails-有没有推荐的方法来处理AJAX表单中的CSRF攻击?,security,grails,csrf,Security,Grails,Csrf,我正在为标准表单使用同步器令牌模式(useToken=true),但是我找不到任何推荐的方法通过AJAX来处理这个问题 编辑 自从发布这篇文章以来,我已经推出了自己的解决方案,其中包含了上面的Grails现有模式 在jqueryajax中,我发布了整个表单(其中包括Grails注入的SYNCHRONIZER\u令牌和SYNCHRONIZER\u URI隐藏字段),以便withForm闭包可以在控制器中按预期执行 问题是,在成功响应时,没有新的令牌集(因为页面没有重新加载,g:form标记库也没有
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
}
谁能确定我是否在不知不觉中在上述解决方案中引入了安全漏洞。这对我来说已经足够了,但我不喜欢用手滚动任何与安全有关的东西。太好了
依我看,你最好同时重置令牌
synchronizertokenholder.store(session).resetToken(params.SYNCHRONIZER\u URI)
如果在同一页面中有多个表单,请定义一个变量来保存从每个ajax请求返回的令牌
顺便说一句,为什么不自己实现令牌模式呢
- 生成一个令牌,例如,
,并将其存储到会话中,url作为密钥UUID.randomuid().toString()
- 在post操作的satrt处检查并重置令牌
complete
中重置令牌,而不是success
。在我的项目中,在同一个页面中有大量ajax重新请求,因此我在ajaxSend和ajaxStop全局中追加并重置了令牌。是的,完成这项工作比成功更重要。对于我自己的实现,我生成令牌并在您点击控制器后立即添加到会话中。我不认为持续再生有什么好处,不太可能有人会在合理的时间内猜到。显然,一旦用户离开并返回页面,就会再次生成一个新页面。