javascript 同源策略及web安全

同源策略为何而生?

JS能够读取/修改网页的值。javascript

一个浏览器中,打开一个银行网站和一个恶意网站,若是恶意网站可以对银行网站进行修改,那么就会很危险。css

你打开了恶意网站和另外一个网站,若是没有同源限制,该恶意网站就能够构造AJAX请求频繁在另外一个网站发广告帖。html

同源策略就是为了解决这类问题而出现的。java

同源策略限制一个加载于A origin的document或者script可以如何和来自于另一个origin的resource交互。同源策略是隔离潜在恶意网页的安全机制。ajax

浏览器的同源策略,限制了来自不一样源的"document"或脚本,对当前"document"读取或设置某些属性。 在浏览器中,<script>、<img>、<iframe>、<link>等标签均可以加载跨域资源,同源策略只对网页的HTML文档作了限制,对加载的其余静态资源如javascript、css、图片等仍然认为属于同源chrome

源的定义

两个网页只有具备相同的protocol,port以及host才被认为是具备相同的origin的。跨域

好比http://xxx.yyy.com:8000/zzz/page.html和http://xxx.yyy.com:8000/kkk/index.html具备相同的originpromise

about:blankjavascript: and data: URLs则从加载那个URL的文件中继承origin.浏览器

同源策略控制了异源之间的互操做,好比,当你使用XMLHttpRequest或者一个<img>元素时就存在这个问题。这些互操做(interactions)典型地放在三个category中:安全

  • cross-origin writes一般是被容许的,好比links,redirect,或者提交一个表单form.
  • cross-origin embedding也一般是被容许的,例如:
    • 使用<script src="..."></script>引入的javascript,这种状况下关于语法错误的错误消息只在同源的脚本中存在;(Content-Type:text/javascript或者application/javascript)
    • 使用<link rel="stylesheet" href="...">来引入的css。注意因为css的语法rule,跨域的css须要一个合适的content-type header (Content-Type:text/css)
    • 使用<img>标签引入的图片,包括PNG,JPEG,GIF,BMP,SVG等。。。
    • 使用<video><embed>或者<applet>来引入的plug-in
    • 使用@font-face引入的字体.可是要注意虽然chrome能很好的工做,可是有些浏览器,好比firefox,ie可能不容许非同源的字体文件被加载,这种状况下,若是使用你本身的CDN网络(这很广泛),则须要配置
      # Apache config
      <FilesMatch ".(eot|ttf|otf|woff)">
      	Header set Access-Control-Allow-Origin "*"
      </FilesMatch>
    • 任何使用<frame>和<iframe>引入的东西。注意:一个网站能够经过使用X-Frame-Options 头来防止你本身的网页被别人frame过去!
  • cross-origin read通常是不容许的,可是通常若是经过embed方式来调用则每每会泄漏部分读的权限。好比,你能够读取到embedded image的宽和高  

如何容许跨源访问呢?使用CORS机制吧

 

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/public-data/';
   
function callOtherDomain() {
  if(invocation) {    
    invocation.open('GET', url, true);
    invocation.onreadystatechange = handler;
    invocation.send(); 
  }
}

 

 

 

GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
Origin: http://foo.example


HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.0.61 
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

 

 

 

如何阻止跨域(源)访问呢?

  • 为了组织cross-origin writes,经过判断一个在request中存在的不易猜出的token(CSRF)TOKEN。注意你必须阻止cross-origin reads of pages that know this token.
  • 为了阻止cross-origin reads of a resource,必须确保它是不能被embedded(not embeddable)。一般,咱们是须要阻止embedding的,由于embedding一个resource一般会泄漏它的部分信息的!
  • 为了阻止cross-origin embedding,确保你的资源不能被翻译为上述embeddable格式中的任何一种。浏览器大多数状况下并不会respect Content-Type.好比若是你将<script>tag指向一个html文档,那么浏览器则将尽本身所能将HTML解析为javascript.当你的资源不是一个你站点的入口时,你可使用CSRF token来阻止embedding.

Cross-orgin script API access

Javascript API,好比iframe.contentWindow, window.parent, window.open,window.opener容许documents来直接引用彼此。当两个document不一样源时,这些reference则仅对Window和Location对象开放至关有限的访问权限,下面将分别列出。

https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

不遵循同源限制的标签:

<script>  <img>  <iframe>中的src,href均可以任意连接网络资源,至关于对所要求的源进行了一次请求。

源继承:

来自about:blank,JavaScript:和data:URLs中的内容,继承了将其载入的文档所指定的源,由于它们的URL自己未指定任何关于自身源的信息。

AJAX跨域的问题

Ajax (XMLHttpRequest)请求应该受到同源策略的限制,可是咱们来看实际状况:

    Ajax经过XMLHttpRequest可以与远程的服务器进行信息交互,另外XMLHttpRequest是一个纯粹的Javascript对象,这样的交互过程,是在后台进行的,用户不易察觉。

    所以,XMLHTTP实际上已经突破了原有的Javascript的安全限制

    举个例子:

        假设某网站引用了其它站点的javascript,这个站点被compromise并在javascript中加入获取用户输入并经过ajax提交给其余站点,这样就能够源源不断收集信息。

        或者某网站由于存在漏洞致使XSS注入了javascript脚本,这个脚本就能够经过ajax获取用户信息并经过ajax提交给其余站点,这样就能够源源不断收集信息。

   若是咱们又想利用XMLHTTP的无刷新异步交互能力,又不肯意公然突破Javascript的安全策略,能够选择的方案就是给XMLHTTP加上严格的同源限制

   这样的安全策略,很相似于Applet的安全策略。IFrame的限制还仅仅是不能访问跨域HTMLDOM中的数据,而XMLHTTP则根本上限制了跨域请求的提交。(实际上下面提到了CORS已经放宽了限制)

   随着Ajax技术和网络服务的发展,对跨域的要求也愈来愈强烈。下面介绍Ajax的跨域技术。    

2.1 JSONP

请参考: http://www.jb51.net/article/75484.htm

    JSONP技术实际和Ajax没有关系。咱们知道<script>标签能够加载跨域的javascript脚本,而且被加载的脚本和当前文档属于同一个域。所以在文档中能够调用/访问脚本中的数据和函数。若是javascript脚本中的数据是动态生成的,那么只要在文档中动态建立<script>标签就能够实现和服务端的数据交互。

    JSONP就是利用<script>标签的跨域能力实现跨域数据的访问,请求动态生成的JavaScript脚本同时带一个callback函数名做为参数。其中callback函数本地文档的JavaScript函数,服务器端动态生成的脚本会产生数据,并在代码中以产生的数据为参数调用callback函数。当这段脚本加载到本地文档时,callback函数就被调用。

相关文章
相关标签/搜索