一、瀏覽器的同源策略
同源策略:不同域的客戶端腳本在未經授權的情況下不能讀寫對方的資源。
這里有幾個關鍵詞:域、腳本、授權、讀寫、資源
1、同域要求兩個站點:同協議、同域名、同端口。下表展示了所列站點與http://www.a.com是否同域的情況。
站點 | 是否同域 | 原因 |
https://www.a.com | 不同域 | 協議不同,http和https是不同的協議 |
http://map.a.com | 不同域 | 域名不同,map子域和www子域不同 |
http://a.com | 不同域 | 域名不同,頂級域名和www子域不是一個概念 |
http://www.a.com:8080 | 不同域 | 端口不同,8080和默認的80端口不同 |
http://www.a.com/a/ | 同域 | 滿足同協議、同域名、同端口,只是多了一個目錄 |
2、腳本:主要指JavaScript和ActionScript,當然也包括VBScript(相對較孤立)。
3、授權:如Ajax跨域,默認情況下是不允許跨域訪問的,只有目標站點(假如是http://www.a.com)明確返回http響應頭 Access-Control-Allow-Origin:http://www.e.com時,www.e.com站點上的客戶端腳本才能有權通過Ajax技術對www.a.com上的數據進行讀寫操作。
4、讀寫權限:web上的資源有很多,有的只有讀權限,有的同時擁有讀和寫的權限。比如:http請求頭里的Referer只可讀,而document.cookie則具備讀寫權限。
5、資源:同源策略里的資源是指web客戶端的資源。一般來說,包括:http消息頭、整個DOM樹、瀏覽器存儲(Cookies、FlashCookies、localStorage等)。
如果沒有同源策略,web世界會發生什么:當你登錄網易郵箱,並打開另一個站點e時,e站點上的JavaScript就可以跨域讀取你的網易郵箱數據,導致隱私泄露。
二、信任問題
安全問題從某種程度上講就是信任問題。同源策略也是信任的一種表現,默認情況下,不同源則不信任。下面有兩個關於信任的場景:
1、場景一
一個Web服務器上有兩個網站A和B,黑客入侵目標是A,但是直接入侵A遇到了巨大困難,而入侵B卻成功了。由於A與B之間過於信任(在同一個文件系統里,且沒有有效的文件權限配置),未能做很好的分離,黑客就可以輕松地攻克網站A。
2、場景二
網站本身是很安全的,由於嵌入了第三方內容(如統計腳本),建立了信任關系,如果第三方的統計腳本被黑客掛馬,將導致網站不安全。雖然這樣不會導致你的網站直接被入侵,但卻危害到了訪問你網站的廣大用戶。
三、前端安全的主要三大類
Web前端安全主要包括跨站腳本(XSS)、跨站請求偽造(CSRF)、界面操作劫持這三大類。
1、XSS
XSS發生在目標網站中目標用戶的瀏覽器層面上,當用戶瀏覽器渲染整個html文檔的過程中出現了不被預期的腳本指令並執行時,XSS就會發生。也可以通俗地總結XSS為:想盡一切辦法將你的腳本內容在目標網站中目標用戶的瀏覽器上解析執行即可。
場景:
http://www.a.com/xss/reflect.php的代碼如下,
<?php echo $_GET['x']; ?>
輸入x的值未經任何過濾就直接輸出,可以提交:
http://www.a.com/xss/reflect.php?x=<script>alert(1)</script>
服務器端解析時,echo就會完整地輸出<script>alert(1)</script>到響應體中,然后瀏覽器解析執行觸發。
2、CSRF
對於CSRF來說,它的請求有兩個關鍵點:跨站點的請求與請求是偽造的。
跨站點請求的來源是其他站點,比如,目標網站的刪除文章功能接收到來自惡意網站客戶端(JavaScript、Flash、HTML等)發出的刪除文章的請求,這個請求就是跨站點的請求,目標網站應該區分請求來源。
如果請求的發出不是用戶的意願,那么這個請求就是偽造的。
場景:
目標網站A:www.a.com 目標網站B:www.b.com
目標網站A上有一個刪除文章的功能,通常是用戶單擊“刪除鏈接”時才會刪除文章,這個鏈接是www.a.com/blog/del?id=1,id代表不同的文章。
CSRF思路,步驟如下:
- 在惡意網站B上編寫一個CSRF頁面(www.b.com/csrf.htm),考慮用代碼<img src=http://www.a.com/blog/del?id=1/>向目標網站A發出一個GET請求的方法。
- 然后欺騙已經登錄目標網站A的用戶訪問www.b.com/csfr.htm頁面,攻擊發生。
這里攻擊過程有三個關鍵點:跨域發出了一個GET請求、可以無JavaScript參與、請求是身份認證后的。
3、界面操作劫持
界面操作劫持是一種通過在可見輸入控件上覆蓋一層不可見的框(iframe),使得用戶誤以為在操作可見控件,而實際上操作行為被不可見框劫持,執行不可見框的惡意支持代碼,從而導致用戶在不知情的情況下被竊取敏感信息、篡改數據等。
下面是一個點擊劫持的簡單例子,clickjacking.htm代碼如下:
<style> #click{ width:100px; top:20px; left:20px; position:absolute; z-index:1 } #hidden{ height:50px; width:120px; position:absolute; filter:alpha(opacity=50); opacity:0.5; z-index:2 } </style> <input id="click" value="Click me" type="button"/> <iframe id="hidden" src="inner.htm" scrolling="no"></iframe>
嵌入的inner.htm代碼如下:
<input style="width:100px;" value="Login" type="button" onclick="alert('test')"/>