zoukankan      html  css  js  c++  java
  • javascript 同源策略及web安全

    同源策略为什么而生?

    JS可以读取/修改网页的值。

    一个浏览器中,打开一个银行网站和一个恶意网站,如果恶意网站能够对银行网站进行修改,那么就会很危险。

    你打开了恶意网站和另一个网站,如果没有同源限制,该恶意网站就可以构造AJAX请求频繁在另一个网站发广告帖。

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

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

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

    源的定义

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

    比如http://xxx.yyy.com:8000/zzz/page.html和http://xxx.yyy.com:8000/kkk/index.html具有相同的origin

    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函数就被调用。

  • 相关阅读:
    报表设计器的使用之一:入门
    统计图开发之二:点图元
    统计图开发之一:画法定义
    集算器之五:序表
    集算器之四:程序流程
    忏悔录
    请不要离我而去
    所想和所做 所梦和所成
    做出改变,不断改变。
    Linux 操作命令
  • 原文地址:https://www.cnblogs.com/kidsitcn/p/5036682.html
Copyright © 2011-2022 走看看