我们有服务于 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 相关的正确值?