同源策略
同源策略是一個重要的安全策略,它用於限制同一個 origin 的文檔或者它加載的腳本如何能與另一個源的資源進行交互,它能幫助阻隔惡意文檔,減少可能被攻擊的媒介
Origin 源
源的組合
- 協議(http、https)
- 域(myapp.com、localhost、localhost.tiangolo.com)
- 端口(80、443、8080)
https://www.cnblogs.com
不同的源的寫法
- http://localhost
- https://localhost
- http://localhost:8080
即使它們都是 localhost,但它們使用不同的協議或端口,因此它們是不同的 Origin 源
再來一個栗子
下表給出了與 URL http://store.company.com/dir/page.html 的源進行對比的示例
| URL | 結果 | 原因 |
|---|---|---|
http://store.company.com/dir2/other.html |
同源 | 只有路徑不同 |
http://store.company.com/dir/inner/another.html |
同源 | 只有路徑不同 |
https://store.company.com/secure.html |
失敗 | 協議不同 |
http://store.company.com:81/dir/etc.html |
失敗 | 端口不同 ( http:// 默認端口是80) |
http://news.company.com/dir/other.html |
失敗 | 主機不同 |
重點
http://127.0.0.1:8080 和 http://localhost:8080 是不同源的哦!!雖然 localhost 就是 127.0.0.1
源的修改
- 滿足某些限制條件的情況下,頁面是可以修改它的源
- 可以通過 document.domain 的值設置為其當前域或其當前域的父域
- 如果將其設置為其當前域的父域,則父域將用於后續同源檢查
比如我的博客地址 https://www.cnblogs.com/poloyy/
在 F12 Console 中敲
document.domain
會得到
'www.cnblogs.com'

改變源
document.domain = "cnblogs.com"
改成當前域的父域
這個頁面將會成功通過與 http://cnblogs.com/dir/page.html 的同源檢查

但是不能將 cnblogs.com 改成 cnblogscool.com ,因為它不是 cnblogs.com 的父域

兩種同源策略
- DOM 同源策略:禁止對不同源頁面 DOM 進行操作。這里主要場景是 iframe 跨域的情況,不同域名的 iframe 是限制互相訪問的
- XMLHttpRequest 同源策略:禁止使用 XHR 對象向不同源的服務器地址發起 HTTP 請求
為什么要有同源策略(跨域限制)
如果沒有 DOM 同源策略
不同域的 iframe 之間可以相互訪問,那么黑客可以這樣進行攻擊:
-
做一個假網站,里面用 iframe 嵌套一個銀行網站 http://mybank.com
-
把 iframe 覆蓋到整個頁面,這樣用戶進來除了域名,別的部分和銀行的網站沒有任何差別。
-
這時如果用戶輸入賬號密碼,我們的主網站可以跨域訪問到 http://mybank.com 的 dom 節點,就可以拿到用戶的賬戶密碼了
如果沒有 XMLHttpRequest 同源策略
那么黑客可以進行 CSRF(跨站請求偽造) 攻擊:
-
用戶登錄了自己的銀行頁面 http://mybank.com,http://mybank.com 向用戶的 cookie 中添加用戶標識
-
用戶瀏覽了惡意頁面 http://evil.com,執行了頁面中的惡意 AJAX 請求代碼
-
http://evil.com 向 http://mybank.com 發起 AJAX HTTP 請求,請求會默認把 http://mybank.com 對應 cookie 也同時發送過去
-
銀行頁面從發送的 cookie 中提取用戶標識,驗證用戶無誤,response 中返回請求數據,此時數據就泄露了
-
而且由於 Ajax 在后台執行,用戶無法感知這一過程
總結
- 同源策略確實能規避一些危險,不是說有了同源策略就安全,只是說同源策略是一種瀏覽器最基本的安全機制
- 能提高一點攻擊的成本
