ajax - 相同域请求的来源和主机 header

标签 ajax http rest http-headers csrf

我们有服务于 AJAX 请求的 RESTful JSON 端点,希望支持跨源资源共享。我们正在锁定一切以确保我们不必担心跨站点请求伪造 (CSRF) 攻击。我们使用的部分方法是检查 Origin header 是否存在,并验证它是否包含在已批准的 Origins 白名单中。但是,我们注意到某些浏览器(其中包括 Chrome 和 Safari)在 AJAX POST 请求中包含 Origin header ,即使来自同一域(因此不是 CORS 请求)也是如此。

由于我们不希望要求我们的用户必须将提供 REST 端点的同一域列入白名单,因此我们希望自动确定给定请求是“同一域”还是“跨域” .为此,目前我们最好的尝试是观察是否存在 Origin header ,如果存在,则将其与 Host header 的值进行比较。我们的逻辑是,如果 Origin 与 Host 匹配,则此请求必须是“相同域”,因此我们不需要检查白名单中的 Origin。

这是我们正在考虑用于实现此目的的服务器端 JS 代码片段:

     if (typeof (headers["Origin"]) !== "undefined" &&
         headers["Origin"].replace(new RegExp("^.*?//"), "") !== headers["Host"] &&
         !contains(allowedOrigins, headers.Origin) ) {
         return false;
     } else {
         return true;
     }

正则表达式比较是必需的,因为 Origin header 会像这样进来:

http://localhost:8080

而主机 header 将如下所示:

localhost:8080

因此我使用该正则表达式去除了领先的 http://。

问题是我们还没有看到任何其他实现使用或讨论这种方法。这让我们担心,出于某种原因,这可能不是一种合适的方法。因此,问题是 - 比较 Host header 和 Origin header 是否是确定请求是否来自同一域的安全方法

此外,是否如我所展示的那样从 Origin 中删除领先的协议(protocol)://总是会产生与 Host 相关的正确值?

最佳答案

我建议您改为检查 Ajax header : X-Requested-With:XMLHttpRequest

同源 Ajax 可以添加自定义 header ,几乎所有流行的框架(例如 jQuery)都添加了 X-Requested-With: XMLHttpRequest。

然而,对于 CORS,自定义 header 会引发飞行前 HTTP OPTIONS 请求。

因此,如果您看到没有预检的 X-Requested-With: XMLHttpRequest(或任何其他自定义 header ),您就知道这是同源 Ajax 调用。

关于ajax - 相同域请求的来源和主机 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14444914/

相关文章:

jquery - 使用 Tornado 向ajax发送响应

ASP.NET AJAX 部分渲染

node.js - 我无法在 Node 中发出 Web 请求

java - 连接到需要用户/密码的网络

java - BufferedReader 不一致地卡在我套接字的输入流上

javascript - 每 N 次迭代创建单元格并包装在父级中

javascript - 仅使用一个js文件进行多个php ajax调用

ajax - 通过表行启动方法

Java REST API for 循环

rest - 如何通过 firefox 插件 RESTClient 更改 GET-Request 的 Content-Type