同源策略及解决

概念:同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准。它最早出自Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不同源装载。

这里的同源指的是:同协议,同域名和同端口。标记时,浏览器会访问src属性中的URL。这样会导致将查询字符串中的信息发送给服务器。在清单1中,所传递的是username和reservation作为名称值对传递。此外,查询字符串还包含向服务器请求的输出格式和回调函数的名称(即showItinerary)。标记加载后,会执行回调函数,并通过回调函数的参数把从服务返回的信息传递给该回调函数。

精髓:

它的精髓很简单:它认为自任何站点装载的信赖内容是不安全的。当被浏览器半信半疑的脚本运行在沙箱时,它们应该只被允许访问来自同一站点的资源,而不是那些来自其它站点可能怀有恶意的资源。

为什么要有同源限制?

我们举例说明:比如一个黑客程序,他利用IFrame把真正的银行登录页面嵌到他的页面上,当你使用真实的用户名,密码登录时,他的页面就可以通过Javascript读取到你的表单中input中的内容,这样用户名,密码就轻松到手了。

Ajax应用:

在Ajax应用中这种安全限制被突破。

在普通的Javascript应用中,我们可以修改Frame的href,或者IFrame的src,以实现GET方式的跨域提交,但是却不能访问跨域的Frame/IFrame中的内容。

而Ajax它通过XMLHTTP进行异步交互,这个对象同样能够与远程的服务器进行信息交互,而且更加危险的是,XMLHTTP是一个纯粹的Javascript对象,这样的交互过程,是在后台进行的,不被用户察觉。因此,XMLHTTP实际上已经突破了原有的Javascript的安全限制。

如果我们又想利用XMLHTTP的无刷新异步交互能力,又不愿意公然突破Javascript的安全策略,可以选择的方案就是给XMLHTTP加上严格的同源限制。这样的安全策略,很类似于Applet的安全策略。IFrame的限制还仅仅是不能访问跨域HTMLDOM中的数据,而XMLHTTP则根本上限制了跨域请求的提交。

浏览器支持:而IE其实给这个安全策略开了两个想当然的后门,一个是:他假设你的本地文件,自然清楚将会访问什么内容,所以任何你的本地文件访问外部数据,都不会收到任何的警告。另一个是:当你访问的网站脚本打算访问跨域的信息时,他居然仅仅是弹出一个对话框来提醒你一下。如果一个欺诈网站,采用这样的手段,提供一个假页面给你,然后通过XMLHTTP帮你远程登录真实的银行服务器。只要10个用户里,有一个用户糊涂一下,点了一个确定。他们的盗取帐号行为,就成功了!你想想看,这是何等危险的事情!

FireFox就不是这样的做法,缺省的情况下,FireFox根本就不支持跨域的XMLHTTP请求,根本就不给黑客这样的机会。

避免同源策略:

JSON和动态脚本标记

<script type="text/javascript"

src="http://travel.com/findItinerary?username=sachiko&

reservationNum=1234&output=json&callback=showItinerary" />

当JavaScript代码动态地插入<script>标记时,浏览器会访问src属性中的URL。这样会导致将查询字符串中的信息发送给服务器。在清单1中,所传递的是username和reservation作为名称值对传递。此外,查询字符串还包含向服务器请求的输出格式和回调函数的名称(即showItinerary)。标记加载后,会执行回调函数,并通过回调函数的参数把从服务返回的信息传递给该回调函数。标记时,浏览器会访问src属性中的URL。这样会导致将查询字符串中的信息发送给服务器。在清单1中,所传递的是username和reservation作为名称值对传递。此外,查询字符串还包含向服务器请求的输出格式和回调函数的名称(即showItinerary)。标记加载后,会执行回调函数,并通过回调函数的参数把从服务返回的信息传递给该回调函数。

标记时,浏览器会访问src属性中的URL。这样会导致将查询字符串中的信息发送给服务器。在清单1中,所传递的是username和reservation作为名称值对传递。此外,查询字符串还包含向服务器请求的输出格式和回调函数的名称(即showItinerary)。标记加载后,会执行回调函数,并通过回调函数的参数把从服务返回的信息传递给该回调函数。

Ajax代理

Ajax代理是一种应用级代理服务器,用于调解Web浏览器和服务器之间的HTTP请求和响应。Ajax代理允许Web浏览器绕过同源策略,这样便可以使用XMLHttpRequest访问第三方服务器。要实现这种绕过,有如下两种方法可供选择:

客户端Web应用程序知道第三方URL并将该URL作为HTTP请求中的一个请求参数传递给Ajax代理。然后,代理将请求转发给[url]www.remoteservice.com[/url]。注意,可以把代理服务器的使用隐藏在Web应用程序开发人员所使用的Ajax库的实现中。对于Web应用程序开发人员而言,它看上去可能完全不具有同源策略。

客户端Web应用程序不知道第三方URL,并且尝试通过HTTP访问Ajax代理服务器上的资源。通过一个预定义的编码规则,Ajax代理将所请求的URL转换为第三方服务器的URL并代表客户检索内容。这样一来,Web应用程序开发人员看上去就像是在和代理服务器直接进行通信。

Greasemonkey

Greasemonkey是一个Firefox扩展,它允许用户动态地对Web页面的样式和内容进行修改。Greasemonkey用户可以把用户脚本(user script)文件与一个URL集合建立关联。当浏览器通过该URL集合加载页面时,便会执行这些脚本。Greasemonkey为用户脚本的API提供了额外的许可(与运行在浏览器沙盒中的脚本的许可相比较)。

GM_XMLHttpRequest是其中的一个API,它从本质上说就是一个不具有同源策略的XMLHttpRequest。用户脚本可以将浏览的内置XMLHttpRequest替代为GM_XMLHttpRequest,从而许可XMLHttpRequest执行跨域访问。

GM_XMLHttpRequest的使用只能通过用户同意的途径才能受到保护。也就是说,Greasemonkey只有在建立新用户脚本与特定URL的集合之间的关联时才会要求用户配置。然而,不难想象一些用户可能会被欺骗,在没有完全理解其后果时就接受该安装。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 五十三:请解释 JavaScript 中 this 是如何工作的。1.方法调用模式当一个函数被保存为一个对象的属性...
    Arno_z阅读 3,715评论 0 2
  • AJAX 原生js操作ajax 1.创建XMLHttpRequest对象 var xhr = new XMLHtt...
    碧玉含香阅读 8,607评论 0 7
  • 3月15日 1. 下列JavaScript代码执行后,依次alert的结果是? 1 3 undefined -1 ...
    福尔摩鸡阅读 5,979评论 0 4
  • 1.几种基本数据类型?复杂数据类型?值类型和引用数据类型?堆栈数据结构? 基本数据类型:Undefined、Nul...
    极乐君阅读 10,956评论 0 106
  • 小的时候不懂得问题都可以去问爸爸妈妈,他们一直都会很耐心的告诉我们 长大了之后,我们会通过各种各样的途径,去认识自...
    honeymei阅读 2,415评论 0 0