3

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

由于我们不希望我们的用户必须将提供 REST 端点的同一个域列入白名单,因此我们希望自动确定给定请求是“同域”还是“跨域”。为此,现在我们最好的尝试是观察是否存在 Origin 标头,如果存在,请将其与 Host 标头的值进行比较。我们的逻辑是,如果 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 标头看起来像这样:

http://localhost:8080

而 Host 标头将如下所示:

localhost:8080

所以我用那个正则表达式去掉前面的 http://。

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

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

4

2 回答 2

3

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

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

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

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

于 2013-01-29T16:59:04.117 回答
0

如果您想切换到 HTTPS或者我们可以说在跨协议请求的情况下,您当前将 Host 标头与 Origin 标头进行比较以确定相同来源的方法将失败。

就像您的代码会将这两个来源视为相同。

Origin : http://www.example.com Origin : https://example.com

其他方法将使用HTTP Referer标头。但我不会更喜欢使用它,因为欺骗它不是一项不可能完成的任务。

我的建议会比抱歉更好。在允许的来源列表中添加一个额外的项目不会给你带来太多痛苦。

于 2013-01-30T12:43:38.097 回答