我有一个现有的rails后端网站,它使json调用服务器。现在,我正在开发一个移动iOS应用程序,以使用相同的后端并在json中发送调用。但是,移动请求失败了:
WARNING: Can't verify CSRF token authenticity
搜索stackoverflow时,许多人建议使用以下内容禁用csrf检查json调用:
# Or this in your application_controller.rb
def verified_request?
if request.content_type == "application/json"
true
else
super()
end
end
但我的问题是,我不明白这是如何阻止json格式的csrf攻击的?攻击者总是可以从他们的站点向我们的端点发送json请求。任何人都有这方面的见解?我找不到任何明确的答案。
答案 0 :(得分:2)
使用Flash非常容易利用您所描述的内容:
var request:URLRequest = new URLRequest("http://stackoverflow.com");
request.requestHeaders.push(new URLRequestHeader('Content-Type', 'application/json'));
request.data = unescape('{"a":1,"b":{"c":3}}');
request.method = URLRequestMethod.POST;
navigateToURL(request, '_blank');
如果查看CSRF prevention cheat sheet,您可以检查引用来确保它来自您信任的域。如果引用者为空,那么它可能来自https url,因此应该被视为失败。依赖Ruby的CSRF令牌是CSRF保护的一种更强大的形式。
答案 1 :(得分:1)
这是对ajax
的修复从rails获取csrf_token或从meta
获取其他内容// js file
var csrf_token = $('meta[name=csrf-token]').attr('content');
或
//js.erb file
var csrf_token = "<%= request.session["<%= _csrf_token %>"] %>";
然后将其添加到js
$("body").bind("ajaxSend", function(elm, xhr, s){
if (s.type == "POST") {
// place lines mentioned above here
// line goes here...
xhr.setRequestHeader('X-CSRF-Token', csrf_token);
}
});
答案 2 :(得分:0)
您可以采取的一种方法是保留CSRF检查,但根据存在的http标头禁用。如果您的json请求具有JWT令牌,则可以在相关控制器中执行类似的操作。
protect_from_forgery with: :exception, unless: -> { some_auth_token.valid? }
提交表单将无法设置http标头,因此csrf将对此加以保护。
您的json请求应该有一个Authorization
标头,以确保安全。