我在我的网站上启用了Codeigniter的CSRF保护,该保护使用AJAX提交用户表单并处理需要通过AJAX提交数据的其他用户交互。结果我遇到了“不允许操作”服务器端错误。我很快发现,只有我通过AJAX收集和提交的javascript数据被传递到服务器,因此没有发送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 :(得分:2)
我想将它添加到Ajax设置中。设置一次并让它自动将其添加到所有请求的发布数据中。
$.ajaxSetup({
data: {
csrf_test_name: $("input[name='csrf_test_name']").val()
}
});
答案 1 :(得分: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', ... }
。