<pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
    <pre id="vvttv"></pre>

      <p id="vvttv"></p>

          <p id="vvttv"></p>

                <p id="vvttv"></p>

                <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                  <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                    <p id="vvttv"></p>

                    原文地址:http://drops.wooyun.org/tips/151

                    同源策略


                    同源策略的文檔模型

                    同源策略(Same Origin policy,SOP),也稱為單源策略(Single Origin policy),它是一種用于Web瀏覽器編程語言(如JavaScript和Ajax)的安全措施,以保護信息的保密性和完整性。

                    同源策略能阻止網站腳本訪問其他站點使用的腳本,同時也阻止它與其他站點腳本交互。

                    原始資源 要訪問的資源 非IE瀏覽器 IE瀏覽器
                    http://example.com/a/ http://example.com/b/ 可以訪問 可以訪問
                    http://example.com/ http://www.example.com/ 主機不匹配 主機不匹配
                    http://example.com/a/ https://example.com/a/ 協議不匹配 協議不匹配
                    http://example.com:81/ http://example.com/ 端口不匹配 可以訪問

                    同源策略一開始是為了管理DOM之間的訪問,后來逐漸擴展到Javascript對象,但并非是全部。

                    例如非同源的腳本之間可以調用location.assign()和location.replace()。

                    同源策略在提高了安全性,但同時也降低了靈活性。

                    例如很難將login.example.com與payments.example.com兩個域之間的數據可以方便的傳送。

                    介紹兩種解決方式:document.domain和postMessage()。

                    javascript允許子域之間使用頂級域名。

                    例如login.example.com和payments.example.com都可以進行如下設置:

                    document.domain="example.com"
                    

                    設置這個屬性之后,子域之間可以方便的通信,需注意的是協議和端口號必須相同。

                    原始資源 訪問的資源 結果
                    URL document.domain URL document.domain
                    http://www.example.com/ example.com http://payments.example.com/ example.com 可以訪問
                    http://www.example.com/ example.com https://payments.example.com/ example.com 協議不匹配
                    http://payments.example.com example.com http://example.com/ (不設置) 拒絕訪問
                    http://www.example.com/ (不設置) http://www.example.com example.com 拒絕訪問

                    postMessage()是HTML5的一個API接口,由于比較新,所以在IE6和IE7中不支持。 1 向另外一個iframe發送消息:

                    var message = 'Hello' + (new Date().getTime());
                        window.parent.frames[1].postMessage(message, '*');
                    

                    iframe1.html需要向iframe2.html發送消息,也就是第二個iframe,所以是window.parent.frames[1]。

                    如果是向父頁面發送消息就是window.parent。

                    postMessage這個函數接收二個參數,缺一不可,第一個參數即你要發送的數據。

                    第二個參數是非常重要,主要是出于安全的考慮,一般填寫允許通信的域名。

                    這里為了簡化,所以使用’*',即不對訪問的域進行判斷。

                    2 另外一個iframe監聽消息事件:

                    iframe2.html中寫個監聽message事件,當有消息傳到iframe2.html時就會觸發這個事件。
                    var onmessage = function(e) {
                        var data = e.data,p = document.createElement('p');
                        p.innerHTML = data;
                        document.getElementById('display').appendChild(p);
                    };
                     //監聽postMessage消息事件
                    if (typeof window.addEventListener != 'undefined') {
                        window.addEventListener('message', onmessage, false);
                     } else if (typeof window.attachEvent != 'undefined') {
                        window.attachEvent('onmessage', onmessage);
                    }
                    

                    如果你有加域名限,比如下面的代碼:

                    window.parent.frames[1].postMessage(message, 'http://www.test.com');
                    

                    就要在onmessage中追加個判斷:

                    if(event.origin !== 'http://www.test.com') return;
                    

                    XMLHttpRequest的同源策略

                    一個簡單的同步XMLHttpRequest請求:

                    var x = new XMLHttpRequest();
                    x.open("POST", "/some_script.cgi", false);
                    x.setRequestHeader("X-Random-Header", "Hi mom!");
                    x.send("...POST payload here...");
                    alert(x.responseText);
                    

                    XMLHttpRequest請求嚴格遵守同源策略,非同源不可以請求。

                    這個API也做過很多測試與改進,下面列出之前的測試方法:

                    var x = new XMLHttpRequest();
                    x.open("POST", "http://www.example.com/", false);
                    // 定義發送內容長度為7
                    x.setRequestHeader("Content-Length", "7");
                    // 構造的http請求。
                    x.send(
                    "Gotcha!\n" +
                    "GET /evil_response.html HTTP/1.1\n" +
                    "Host: www.bunnyoutlet.com\n\n"
                    );
                    

                    現在的瀏覽器都不存在上面的隱患,包括基本都禁用了TRACE方法,防止httponly的cookie泄漏問題等。

                    Web Storage的同源策略

                    Web Storage是由Mozilla的工程師在Firefox1.5中加入的,并且加入了HTML5中,現在的瀏覽器都支持,除了IE6與IE7。

                    JavaScript可以通過localStorage與sessionStorage對Web Storage進行創建,檢索和刪除:

                    localStorage.setItem("message", "Hi mom!"); 
                    alert(localStorage.getItem("message")); 
                    localstorage.removeItem("message");
                    

                    localStorage對象可以長時間保存,并且遵守同源策略。

                    但是在IE8中localStorage會把域名相同但是協議分別為HTTP和HTTPS的內容放在一起,IE9中已修改。

                    在Firefox中,localStorage沒有問題,但是sessionStorage也是會把域名相同的HTTP與HTTPS放在一起。

                    Cookie的安全策略

                    設置Cookie總結

                    在foo.example.com設置cookie,domain設置為:

                    最終cookie的范圍

                    非IE瀏覽器

                    IE瀏覽器

                    設置為空

                    foo.example.com(一個域)

                    *.foo.example.com

                    bar.foo.example.com

                    cookie設置失敗,設置的域是當前域的一個子域

                    foo.example.com

                    *.foo.example.com

                    baz.example.com

                    cookie設置失敗,域名不匹配

                    example.com

                    *.example.com

                    ample.com

                    cookie設置失敗,域名不匹配

                    .com

                    設置失敗,域名太廣,存在安全風險。

                    Cookie中的path參數可以設定指定目錄的cookie。

                    例如設定domain為example.com,path為/some/path/ 在訪問下面url的時候會帶上設定的cookie:

                    http://foo.example.com/some/path/subdirectory/hello_world.txt

                    存在一定的安全風險,因為path的設定沒有考慮到同源策略。

                    httponly屬性可以防止通過document.cookie的API訪問設定的cookie。

                    secure屬性設定后只有在通過https傳輸時才會帶上設定的cookie,可以防止中間人攻擊。

                    Adobe Flash

                    AllowScriptAccess參數:用來控制flash通過ExternallInterface.call()函數調用javascript的時的限制。

                    有三個值:always,never和sameorigin,最后一個值只允許同域的JavaScript操作(08年之前默認為always,現在默認為sameorigin)。

                    AllowNetworking參數:用來控制flash與外部的網絡通訊。

                    可選的值為:all(允許使用所有的網絡通訊,默認值),internal(flash不能與瀏覽器通訊如navigateToURL,但是可以調用其他的API),none(禁止任何的網絡通訊)

                    本地文件

                    由于本地文件都是通過file:協議進行訪問的,由于不存在host,所以無法遵循同源策略。

                    所以本地保存的一個HTML文件,在瀏覽器中通過file:協議訪問后,可以通過XMLHttpRequest或DOM對本地其他文件進行操作。

                    與此同時,也可以對互聯網的其他資源做同樣的操作。各瀏覽器廠商意識到這個問題,并努力做了修改:

                    測試代碼:

                    1.html(1.txt隨機寫一些字符串即可)

                    <script>
                    function createXHR(){
                      return window.XMLHttpRequest?
                      new XMLHttpRequest():
                      new ActiveXObject("Microsoft.XMLHTTP");
                    }
                    function getlocal(url){
                      xmlHttp = createXHR();
                      xmlHttp.open("GET",url,false);
                      xmlHttp.send();
                      result = xmlHttp.responseText;
                      return result;
                    }
                    function main(){
                      url = "file://路徑/1.txt";
                      alert(url);
                      result = getlocal(url);
                      alert(result);
                    }
                    main();
                    </script>
                    

                    結論:

                    1 Chrome瀏覽器(使用WebKit內核的瀏覽器)
                    完全禁止跨文檔的XMLHttpRequest和DOM操作,并禁止了document.cookie和<meta http-equiv="Set-Cookie" ...>的操作。
                    2 Firefox
                    允許訪問同目錄與子目錄里的文件。也可通過document.cookie與<meta http- equiv="Set-Cookie" ...>設定cookie,file:協議下cookie共享,storage也是。
                    3 IE7及以上
                    允許本地文件之間的訪問,但是在執行JavaScript之前會有一個提示,用戶點擊通過之后可以執行,cookie域Firefox類似,但是file:協議下不支持storage。
                    4 IE6
                    允許本地文件的訪問,同時也允許對http協議的訪問,cookie也是一樣。
                    

                    偽URL的域


                    一些web應用用到了偽URL例如about:,javascript:,和data:來創建HTML文檔。

                    這種方法是為了不需要再與服務器通信,可以節約時間更快的響應,但是也帶進了很多安全隱患。

                    about:blank
                    

                    about協議在現在的瀏覽器中有很多用途,但是其中大部分不是為了獲取正常的頁面。

                    about:blank這個URL可以用來被創建DOM對象,例如:

                    <iframe src="about:blank" name="test"></iframe>
                    <script> 
                    frames["test"].document.body.innerHTML = "<h1>Hi!</h1>";
                    </script>
                    

                    在瀏覽器中,創建一個about:blank頁面,它繼承的域為創建它的頁面的域。

                    例如,點擊一個鏈接,提交一個表單,創建一個新窗口,但是當用戶手動輸入about:或者書簽中打開的話,他的域是一個特殊的域,任何其他的頁面都不可以訪問。

                    data:協議
                    

                    data:協議是設計用來放置小數據的,例如圖標之類的,可以減少http請求數量,例如:

                    <img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEBLAEsAAD...">
                    

                    用以下代碼研究域的問題:

                    <iframe src="data:text/html;charset=utf-8,<script>alert(document.domain)</script>" >  
                    

                    在Chrome與Safari中,所有的data:都會賦予一個單獨的,不可獲取的域,而不是從父域中繼承的。

                    Firefox與Opera中,域是繼承于當前頁面。

                    IE8之前的版本不支持data:協議。

                    javascript:和vbscript:

                    javascript:協議允許后面執行javascript代碼,并且繼承了調用的當前域。

                    有些情況會對后面的內容處理兩次,如果代碼正確的話,會把后面的代碼當成html解析,覆蓋掉原來的html代碼:

                    <iframe src='javascript:"<b>2 + 2 = " + (2+2) + "</b>"'> 
                    </iframe>
                    

                      <pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
                      <pre id="vvttv"></pre>

                        <p id="vvttv"></p>

                            <p id="vvttv"></p>

                                  <p id="vvttv"></p>

                                  <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                                    <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                                      <p id="vvttv"></p>

                                      这里只有精品视频