规避同源策略的方法

IT技术 javascript ajax same-origin-policy
2021-01-07 22:04:16

同源政策

我想创建一个关于 HTML/JS同源策略的社区 wiki ,希望能帮助任何搜索此主题的人。这是 SO 上搜索次数最多的主题之一,并且没有统一的 wiki,所以我在这里 :)

同源策略可防止从一个源加载的文档或脚本从另一个源获取或设置文档的属性。该政策可追溯到 Netscape Navigator 2.0。

您最喜欢的绕过同源策略的一些方法是什么?

请保持示例详细,最好还链接您的来源。

6个回答

document.domain方法

  • 方法类型:iframe

请注意,这是一个 iframe 方法,它将 document.domain 的值设置为当前域的后缀。如果是这样,较短的域将用于后续的源检查。例如,假设文档中的脚本http://store.company.com/dir/other.html执行以下语句:

document.domain = "company.com";

该语句执行后,页面将通过原始检查http://company.com/dir/page.html但是,出于同样的原因,company.com 无法设置document.domainothercompany.com.

使用此方法,您将被允许从源自主域的页面上的子域上的 iframe 执行 javascript。此方法不适用于跨域资源,因为 Firefox 等浏览器不允许您将其更改document.domain为完全陌生的域。

来源:https : //developer.mozilla.org/en/Same_origin_policy_for_JavaScript

跨域资源共享方式

  • 方法类型:AJAX

跨域资源共享(CORS) 是 W3C 工作草案,它定义了跨域访问源时浏览器和服务器必须如何通信。CORS 背后的基本思想是使用自定义 HTTP 标头来允许浏览器和服务器充分了解彼此,以确定请求或响应是成功还是失败。

对于一个简单的请求,即使用GETPOST不使用自定义标头且主体为text/plain的请求,将使用名为 的额外标头发送请求OriginOrigin 标头包含请求页面的来源(协议、域名和端口),以便服务器可以轻松确定它是否应该提供响应。示例Origin标题可能如下所示:

Origin: http://www.stackoverflow.com

如果服务器决定应该允许该请求,它会发送一个Access-Control-Allow-Origin标头,回显发送的同一来源或者*它是否是公共资源。例如:

Access-Control-Allow-Origin: http://www.stackoverflow.com

如果缺少此标头,或来源不匹配,则浏览器将拒绝该请求。如果一切顺利,浏览器就会处理请求。请注意,请求和响应都不包含 cookie 信息。

Mozilla 团队在他们关于 CORS 的帖子中建议您应该检查该withCredentials 属性是否存在,以确定浏览器是否通过 XHR 支持 CORS。然后你可以结合XDomainRequest对象的存在来覆盖所有浏览器:

function createCORSRequest(method, url){
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr){
        xhr.open(method, url, true);
    } else if (typeof XDomainRequest != "undefined"){
        xhr = new XDomainRequest();
        xhr.open(method, url);
    } else {
        xhr = null;
    }
    return xhr;
}

var request = createCORSRequest("get", "http://www.stackoverflow.com/");
if (request){
    request.onload = function() {
        // ...
    };
    request.onreadystatechange = handler;
    request.send();
}

请注意,要使 CORS 方法起作用,您需要有权访问任何类型的服务器标头机制,而不能简单地访问任何第三方资源。

来源:http : //www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/

window.postMessage方法

  • 方法类型:iframe

window.postMessage, 当被调用时,导致MessageEvent在任何必须执行的挂起脚本完成时在目标窗口分派a (例如,如果window.postMessage从事件处理程序中调用剩余的事件处理程序,先前设置的挂起超时等)。MessageEvent具有类型消息,data其被设置为提供到所述第一参数的字符串值属性window.postMessage,一个origin对应于窗口调用主文档的原点属性window.postMessage在时间window.postMessage被调用,并且一个source属性,该属性是窗口从这window.postMessage被称为。

要使用window.postMessage,必须附加事件侦听器:

    // Internet Explorer
    window.attachEvent('onmessage',receiveMessage);

    // Opera/Mozilla/Webkit
    window.addEventListener("message", receiveMessage, false);

并且receiveMessage必须声明一个函数:

function receiveMessage(event)
{
    // do something with event.data;
}

场外 iframe 还必须通过postMessage以下方式正确发送事件

<script>window.parent.postMessage('foo','*')</script>

任何窗口都可以在任何其他窗口上访问此方法,无论文档在窗口中的位置如何,都可以随时向其发送消息。因此,任何用于接收消息的事件侦听器都必须首先使用来源和可能的来源属性检查消息发送者的身份。不能低估这一点:未能检查origin和可能的source属性会导致跨站点脚本攻击。

来源:https : //developer.mozilla.org/en/DOM/window.postMessage

我希望我不会太晚得到答案:唯一的问题是,本地主机总是例外吗?总是不允许吗?我应该停止通过我的本地主机进行测试吗?
2021-02-20 22:04:16
我不知道为什么,但是当我设置: Access-Control-Allow-Origin: http://www.stackoverflow.com/而不是:Access-Control-Allow-Origin: http://www.stackoverflow.com(url 末尾的斜线)时,它在 Safari 和 FF 中不起作用,但在 Chrome 中起作用。当然,没有斜线在所有浏览器中都可以正常工作。
2021-02-24 22:04:16
可能值得让人们知道该postMessage方法仅适用于支持它的浏览器,因为它是 HTML5 的补充。这个插件试图解释这一点。只是提到它,因为我正在艰难地学习这一点。
2021-02-25 22:04:16

反向代理方法

  • 方法类型:Ajax

在服务器上设置一个简单的反向代理,将允许浏览器使用 Ajax 请求的相对路径,而服务器将充当任何远程位置的代理。

如果在 Apache 中使用mod_proxy,则设置反向代理的基本配置指令是ProxyPass. 它通常如下使用:

ProxyPass     /ajax/     http://other-domain.com/ajax/

在这种情况下,浏览器将能够以/ajax/web_service.xml相对 URL 的形式请求,但服务器将通过充当 的代理来提供服务http://other-domain.com/ajax/web_service.xml

此方法的一个有趣特性是反向代理可以轻松地将请求分发到多个后端,从而充当负载均衡器

我使用 JSONP。

基本上,你添加

<script src="http://..../someData.js?callback=some_func"/>

在您的页面上。

some_func() 应该被调用,以便通知您数据在。

@Erlend:任何人都可以检索网络上提供的任何信息(除非需要适当的身份验证)。信息呈现方式的确切格式不会使这变得更好或更糟,即使它是 JSONP。
2021-02-12 22:04:16
这代表什么 .js 文件 ->“http://..../someData.js....我正在尝试从另一个站点客户端读取 dom,并且需要规避同源策略.
2021-02-24 22:04:16
@T-Bull:问题是 JSONP 不可能进行正确的身份验证。用户登录站点 A,然后转到站点 B,该站点使用 JSONP 脚本标记从 A 加载数据。一如往常。然后用户被诱骗访问恶意站点 C,该站点也使用 JSONP 脚本标签从 A 加载数据。因此,由于用户通过 A 进行了身份验证,C 的所有者现在可以从 A 窃取用户数据。即使用户使用两因素身份验证通过 A 进行身份验证。问题是 JSONP 非常不安全。并且 JSONP 不是演示文稿。这是不安全的数据传输。
2021-03-05 22:04:16
JSONP 有两个问题:a) 您正在向目标域添加脚本标记。他们可以发回任何东西,甚至是普通的 javascript(XSS 攻击)。所以你真的必须相信他们不会做坏事或被黑客入侵 b) 任何其他网页都可以添加相同的脚本标签,并窃取数据,所以永远不要将 JSONP 用于私人数据。
2021-03-07 22:04:16
JSONP 仅支持 HTTP GET。
2021-03-08 22:04:16

AnyOrigin没有一些https网站运行良好,所以我只是写一个开源替代whateverorigin.org,似乎以https很好地工作。

github 上的代码

@neoascetic - 修复了用法……现在需要对 URL 进行编码。
2021-02-13 22:04:16
@DavidTitarenco - 试图了解任何起源的肚子里发生的一些事情让我发疯了。幸运的是,我找到了一篇有帮助的博客文章,现在如果他需要的话,下一个人将拥有一个可用的测试站点。
2021-02-26 22:04:16

克服我发现的同源策略的最新方法是http://anyorigin.com/

该网站的制作使您只需给它任何 url,它就会为您生成 javascript/jquery 代码,让您可以获取 html/data,而不管它的来源。换句话说,它使任何 url 或网页成为 JSONP 请求。

我发现它非常有用:)

这是来自 anyorigin 的一些示例 javascript 代码:

$.getJSON('http://anyorigin.com/get?url=google.com&callback=?', function(data){
    $('#output').html(data.contents);
});
这意味着:a)anyorigin 将能够读取您通过 tem 传输的所有数据 b)anyorigin 可以对您的站点进行 XSS,读取您站点上的所有数据,并向您的用户发送恶意软件(如果 anyorigin 被黑客入侵会发生什么?)
2021-02-09 22:04:16
虽然它给我带来了 https 站点的一些问题,但请查看下面我的开源替代方案:stackoverflow.com/questions/3076414/...
2021-02-12 22:04:16
@Erlend - fork Whatorigin 并将其托管在您自己的服务器上。代码很简单,因此您可以查看它以确保其中没有隐藏任何漏洞。
2021-03-02 22:04:16