Browser Security-同源策略、偽URL的域
同源策略
同源策略的文件模型
同源策略(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>
相關文章
- 同源策略和跨域2020-10-28跨域
- Browser Security-基本概念2020-08-19
- 跨域?如何解決?同源策略?2022-05-03跨域
- 同源策略和跨域訪問2018-05-28跨域
- 由同源策略到前端跨域2017-04-20前端跨域
- 同源策略2020-07-13
- JavaScript的同源策略2015-11-08JavaScript
- 也談談同源策略和跨域問題2016-06-03跨域
- 同源策略詳解2018-09-10
- 瀏覽器的同源策略2013-02-21瀏覽器
- 前端拾遺--http-同源策略和跨域處理2020-03-13前端HTTP跨域
- 瀏覽器同源策略及 Ajax 跨域解決方案2018-07-13瀏覽器跨域
- 前端中的同源策略與三種跨域資源共享方法2019-03-22前端跨域
- FE.B-理解瀏覽器的同源策略與跨域方案2019-02-16瀏覽器跨域
- 同源策略及其解決方案2018-03-20
- javascript 同源策略及web安全2015-12-10JavaScriptWeb
- 再也不學AJAX了!(三)跨域獲取資源 ① - 同源策略2017-12-04跨域
- 淺聊同源策略的一些基礎2019-01-28
- 同源政策與跨域請求2020-02-08跨域
- 請描述你對瀏覽器同源策略的理解2024-11-24瀏覽器
- puppeteer去掉同源策略及請求攔截2020-08-19
- 關於同源策略(Same-origin policy)2016-08-01
- 學習AJAX必知必會(5)~同源策略、解決跨域問題(JSONP、CORS)2022-01-22跨域JSONCORS
- 什麼是跨域,什麼是同源2017-02-24跨域
- Same Origin Policy 瀏覽器同源策略詳解2021-02-25瀏覽器
- HTML input url域2018-10-21HTML
- 面試--同源以及規避同源限制的方法2017-10-05面試
- MicrosoftEdge同源策略不嚴導致任意檔案讀取測試2018-09-10ROS
- 域組策略與本地組策略2015-06-17
- 簡單弄懂同源政策 (Same Origin Policy) 與跨網域 (CORS)2021-12-28CORS
- Explain in detail the steps/processes that occur from the moment you type a URL in a browser and hit enter2015-01-14AI
- UrlReWrite(Url重寫或偽靜態)完美示例原始碼2010-04-08原始碼
- 介紹什麼是同源和什麼是跨域,以及三種解決跨域問題的路徑2020-11-16跨域
- Request模組實戰02 --- 實現簡易網頁採集器(UA偽裝反爬策略、處理有引數url)2020-12-08網頁
- IIS7.0設定 url重寫成html(偽靜態)2020-04-05HTML
- 組策略-處理-作用域2024-05-23
- 瀏覽器端CORS策略+快取策略導致的跨域策略失效問題2017-10-23瀏覽器CORS快取跨域
- THINKPHP3.1開發的企業網站,帶偽靜態url設定2019-05-11PHP網站