2012-07-06 34 views
0

我在我的网站上启用了Codeigniter的CSRF保护,它使用AJAX提交用户表单并处理需要通过AJAX提交数据的其他用户交互。因此,我碰到了“不允许的操作”服务器端错误。我很快就发现只有通过AJAX收集和提交的数据才传递给服务器,因此CSRF代码未被发送。通过AJAX将Codeigniter CSRF字符串传递到服务器

生成的令牌标记的样子:

<input type="hidden" name="csrf_test_name" value="dsflkabsdf888ads888XXXXXX" /> 

所以,在我看来提交令牌服务器进行验证的最简单方法是使用上csrf_test_name jQuery选择得到的值,然后将这个以我的发布数据为服务器进行验证。按下面的代码:

//get CSRF token 
var csrf = $('[name="csrf_test_name"]').val(); 

//build the form data array 
var form_data = { 
    csrf_test_name: csrf, 
    ... ... ... 
    ... ... ... 
} 

//send the form data to the server so it can be stored 
$.ajax({ 
    type: "POST", 
    data: form_data, 
    url: ..., 
    dataType: "html", 
    success: function(msg){ 
     ... ... ... 
    }//end success 
});//end ajax 

我按照这个程序将数据发送到服务器,服务器端错误是固定的,一切工作正常每个Ajax提交。

为了测试这个,我用一个不正确的CSRF令牌进行了硬编码,服务器检测到不一致并返回一个错误代码500,这样在表面上工作。

我的问题是,这是一个安全的方法来做到这一点,是否有一个预期的最佳实践遵循?我已经做了一些谷歌搜索这个,似乎所有其他方法更复杂,我想知道如果我的方式创建一个我看不见/锻炼的攻击媒介。

+0

我使用与您一样的确切方法,它通常是推荐的方法。 AFIK这是安全的,但我不介意更多的意见! – Motive 2012-07-06 22:13:07

+0

这看起来很好,除非你在后端代码中有一些逻辑上的缺陷,这很可能不太可能。我会确保你在不匹配时不会返回500错误,但我想这是一个优先选择的问题。另外请记住,即使是最小的XSS也会在10个中的任何一个中击败任何csrf保护。 – 2012-07-07 13:15:05

+0

感谢您的反馈。我使用的是Codeigniter,并且所有全球XSS过滤器都已打开,因此我应该理解Codeigniter文档以应对大多数攻击 – SimonBarker 2012-07-07 14:11:52

回答

1

更简单的方法是将该csrf传递给$.ajaxSetup(),这种方式随后包含在任何$.ajax()请求中。

var csrf = $('input[name="csrf_test_name"]').val(); 
var data = {}; 
data[CSRF] = csrf; 

$.ajaxSetup({ 'data': data }); 

然后在安装后无需在请求中包含data: { csrf_test_name: 'xxx', ... }

2

我喜欢将它添加到Ajax设置。设置一次,让它自动将它添加到您的所有请求的发布数据。

$.ajaxSetup({ 
    data: { 
     csrf_test_name: $("input[name='csrf_test_name']").val() 
    } 
});