對同源策略與多頁面通信、跨域請求的深刻探索


爲了網頁的安全,如今主要的瀏覽器都遵循了同源策略。同源策略究竟有哪些規範?怎麼體現安全做用?
我的總結同源策略的一個首要宗旨是:javascript

阻止能向外傳輸信息的模塊(如javascript)獲取到來自不一樣源的資源,不能獲取也就從源頭阻止了資源和其中信息的泄露html

很重要的一點是,同源策略阻止的是跨域資源的獲取,而不是阻止跨域的請求,請求能夠正常發出,但返回的內容被阻止,沒法讓JS腳本獲取前端


針對javascript,且看幾個直觀的現象:
一、一個頁面的javascript能獲取到其餘頁面的window。但在非同源的狀況下,只能訪問window少部分屬性和方法。
不一樣源時可訪問屬性方法以下:
方法
window.blur
window.close
window.focus
window.postMessage
屬性
window.closed   Read only.
window.frames  Read only.
window.length   Read only.
window.location Read/write.
window.opener  Read only.
window.parent   Read only.
window.self       Read only.
window.top       Read only.
window.window Read only.
有一些瀏覽器也許會容許訪問更多一些屬性方法。但重要的document,localstorage等確定是沒法讀寫的。
頁面能夠自身設置document.domain,開放其餘一部分域的腳本對自身document、localstorage等的讀寫。
在同源的基礎下,則沒有限制。
二、<script>、<img>、<iframe>、<link>等標籤都能跨域加載內容,但沒法利用這些標籤對外發送加載到的內容。
三、js腳本不能獲取到上述標籤加載回來的內容,也就沒法把這些內容發送出去,只能獲取到內容被瀏覽器解析後瀏覽器基於須要而暴露的信息(如img的width,onload等)。java

一個不直觀的現象:
一、ajax能夠利用用戶身份請求不一樣源的內容,但同源策略阻止了請求回來的內容向javascript的流通,因而沒法泄露到用戶瀏覽器以外。web

這個現象能夠本身架設localhost試驗,後臺正常收到請求並正常回應,可是瀏覽器出顯示沒有跨域資源共享,沒法訪問返回的內容ajax

怎麼體現安全做用?
設想一個場景,用戶打開www.bank.com/bank.html, 又在另外一個標籤裏打開 www.evil.com/evil.html。
此時在同源策略下,evil.html頁面上的js腳本不能訪問操做bank.html頁面的document,localstorage等重要資源。
evil.html能夠利用腳本建立iframe,img,script去加載bank.com的資源,這些資源加載回來後由瀏覽器默認的去解析或呈現,腳本依然沒法獲取加載回來的內容,只能獲得瀏覽器基於須要而暴露的信息(如img的width,onload等)。
evil.html的腳本能夠利用Ajax直接去加載bank.com上的資源,Ajax請求能夠正確發出並返回,但停在了瀏覽器處,同源策略阻止了請求回來的內容向evil.html上腳本的流通
至此evil.html的腳本關於用戶的信息都沒法獲取到。
特別地,從bank.html或者evil.html發送請求到bank.com/charge.html,
二者攜帶的cookie是一樣的,不一樣的是http請求頭的referer,後端只判斷cookie/session的話就會認爲都是真正用戶的請求。因而就造成了跨域請求僞造攻擊(CSRF)。
對此,bank.com後端不傻,它事先發送了惟一標識在bank.html的頁面上,bank.html到charge.html的請求還帶上了惟一標識,後端不只判斷referer,還特地去檢查收到的標識和事先發送的惟一標識是否一致。
evil.html沒法訪問bank.html,因而沒法獲得惟一標識,因而沒法僞造和bank.html發出的同樣的請求。
至此evil.html的腳本一無所得,沒法獲取並泄露信息也沒法僞造請求。後端

綜合以上現象,能夠總結出,同源策略規範了javascript所能獲取的資源和信息,因此用戶即便不當心瀏覽到不良網頁,也還有必定的安全性。跨域

同源策略下,javascript對多頁面之間的通信和多個域的資源獲取都受到了限制,下面簡要介紹在同源策略下一些合理跨域的方法
對於多頁面通信
一、設置document.domain+iframe
二、window.name
三、window.postMessage,window.localstorage
對於跨域資源獲取
四、跨域資源共享CORS(Cross-Origin Resource Sharing)
五、JSONP
六、WebSockets
總結是這些方法都是A去訪問B, B頁面主動開放訪問權限,或者B服務器本身根據請求信息判斷是否對A請求開放並配合A返回合適的響應,因而A能夠跨域獲取資源。
我的以爲後臺代理的方式對前端來講並無跨域,因此就沒有歸結到上面的跨域方法中。瀏覽器


參考文章和跨域方法的詳細介紹請參見如下文章:
JavaScript跨域總結與解決辦法 http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html
Web - JSONP和同源策略漫談 http://www.cnblogs.com/huangjacky/p/4001073.html
(譯)同源策略和跨域訪問 http://blog.csdn.net/shimiso/article/details/21830313
同源策略詳解及繞過 http://www.freebuf.com/articles/web/65468.html
瀏覽器同源政策及其規避方法 http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html 安全

有興趣的能夠看看關於同源策略比較官方的介紹w3c: https://www.w3.org/Security/wiki/Same_Origin_Policywiki: https://en.wikipedia.org/wiki/Same-origin_policyMDN: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

相關文章
相關標籤/搜索