同源策略
所謂同源是指,域名,協議,端口相同。
同源策略(same origin policy)是一種約定,它是瀏覽器最核心也是最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能受到影響??梢哉fWeb是構建在同源策略的基礎之上的,瀏覽器只是針對同源策略的一種實現。
瀏覽器的同源策略,限制了來自不同源的"document"或腳本,對當前“document”讀取或設置某些屬性。
跨站腳本攻擊(XSS)
一、XSS簡介
跨站腳本攻擊,英文全稱是Cross Site Script,本來縮寫是CSS,但是為了和層疊樣式表(Cascading Style Sheet,CSS)有所區別,所以在安全領域叫“XSS”。
XSS攻擊,通常指黑客通過“HTML注入”篡改了網頁,插入惡意的腳本,從而在用戶瀏覽網頁時,控制用戶瀏覽器的一種攻擊。在一開始,這種攻擊的演示案例是跨域的,所以叫“跨站腳本”,但是發展至今,由于JavaScript的強大功能以及網站前端應用的復雜化,是否跨域已經不重要了。
二、XSS的類型:
1. 反射型XSS
反射性XSS只是簡單地把用戶輸入的數據“反射”給瀏覽器。也就是說,黑客往往要誘使用戶“點擊”一個惡意鏈接,才能攻擊成功。反射型XSS也叫做“非持久型XSS”
2.存儲型XSS
存儲型XSS會把用戶輸入的數據“存儲”在服務端。這種XSS具有很強的穩定性。黑客把惡意的腳本保存到服務器,所以這種XSS攻擊也叫做“存儲型XSS”。存儲型XSS通常也叫做“持久型XSS”,因為從效果上來說,它存在的時間是比較長的。
比較常見的一種場景就是,黑客寫下一篇包含有惡意JavaScript代碼的博客文章,博客發表后,所有訪問該博客文章的用戶,都會在他們的瀏覽器中執行這段惡意代碼。
3.Dom Base XSS
通過修改頁面的DOM節點形成的XSS,稱之為Dom Based XSS。
Dom Based XSS從效果上來說也是反射型XSS,單獨劃分出來,是因為Dom Based XSS的形成原因比較特別,所以把它單獨作為一個分類。
三、XSS Payload
XSS攻擊成功后,攻擊者能夠對用戶當前瀏覽的頁面植入惡意腳本,通過惡意腳本,控制用戶的瀏覽器——這些用以完成各種具體功能的惡意腳本,被稱為“XSS Payload”。
XSS Payload實際上是JavaScript腳本(還可以是Flash或者其他客戶端的腳本),所以任何JavaScript腳本能實現的功能,XSS PayLoad都能做到。
一個最常見的XSS PayLoad,就是通過讀取瀏覽器的Cookie對象,從而發起“cookie劫持”攻擊。
Cookie中一般加密保存了當前用戶的登陸憑證。Cookie如果丟失,往往意味著用戶的登陸憑證丟失,換句話說,攻擊者可以不通過密碼,而直接登陸用戶的賬戶。
跨站點請求偽造(CSRF)
一、CSRF簡介
跨站請求偽造(Cross Site Request Forgery),也被稱為one-click attack或者session riding,通??s寫為CSRF或者XSRF, 是一種挾制用戶在當前已登錄的Web應用程序上執行非本意的操作的攻擊方法。
CSRF跟XSS相比,XSS利用的是用戶對指定網站的信任,CSRF 利用的是網站對用戶網頁瀏覽器的信任。
二、CSRF的防御
1.驗證碼
驗證碼被認為是對抗CSRF攻擊最簡潔而有效的防御方法。
CSRF攻擊的過程,往往是在用戶不知情的情況下構造了網絡請求。而驗證碼,則強制用戶必須與應用進行交互,才能完成最終請求。因此,通常情況下驗證碼能夠很好地遏制CSRF攻擊。
2.Referer Check
Referer Check在互聯網中最常見的應用就是“防止圖片盜鏈”。同理,Referer Check也可以用于檢查請求是夠來自合法的“源”。
常見的互聯網應用,頁面與頁面之間都具有一定的邏輯關系,這就使得每個正常請求的Referer具有一定的規律。
比如一個“論壇發帖”的操作,在正常情況下需要先登錄到用戶后臺,或者訪問有發帖功能的頁面。在提交“發帖”的表單時,Referer的值必然是發帖表單所在的頁面。如果Referer值不是這個頁面,甚至不是發帖網站的域,則極有可能是CSRF攻擊。
Referer Check的缺陷在于,服務器并非什么時候能都取到Referer。很多用戶處于保護隱私的考慮,限制了Referer的發送。在某些情況下,瀏覽器也不會發送Referer,比如從HTTPS跳轉到HTTP,出于安全考慮,瀏覽器也不會發送Referer。
出于以上種種原因,我們還是無法依賴于Referer Check作為防御CSRF攻擊的主要手段。但是,通過Referer Check來監控CSRF攻擊的發生,倒是一種可行的方法。
3.Anti CSRF Token
-
CSRF的本質
CSRF為什么能夠攻擊成功?其本質原因是重要操作的所有參數都是可以被攻擊者猜測到的。
攻擊者只有預測出URL的所有參數與參數值,才能成功地構造一個偽造的請求;反之,攻擊者將無法攻擊成功。出于這個原因,可以想到一個解決方法:把參數加密,或使用一些隨機數,從而讓攻擊者無法猜測到參數值。
但是這個方法也存在一些問題。首先,加密或者混淆后的URL將變得非常難度,對用戶非常不友好。其次,如果加密的參數每次都要改變,某些URL將無法被用戶收藏。最后,普通的參數,如果也被加密或哈希,將會給數據分析工作帶來很大的困擾。(因為數據分析工作常常需要用到參數的明文)
因此,我們需要一個通用的方法來解決這個問題,那就是Anti CSRF Token。這個token的值是隨機的,不可預測的。
Token需要足夠隨機,必須使用足夠安全的隨機數生成算法,或者采用真隨機數生成器。另外,Token應該是一個秘密,為用戶與服務器所共同持有,不能被第三者知曉。在實際應用中,Token可以放在用戶的Session中,或者瀏覽器的Cookie中。
Token需要同時放在表單和Session中,在提交請求時,服務器只需庁表單中的Token與Session(或CooKie)中的Token是否一致,如果一致,則認為是合法請求,如果不一致,或者有一個是空,則認為請求不合法,可能發生了CSRF攻擊。
-
Token的使用原則
防御CSRF的Token,是根據“不可預測性原則”設計的方案,所以Token的生成一定要足夠隨機,需要使用安全的隨機數生成器來生成Token。
這個Token的目的不是為了防止重復提交,所以為了使用方便,可以允許在一個用戶的有效聲明周期內,在Token消耗掉前都使用同一個Token。但是如果用戶已經提交了表單,則這個Token已經消耗掉,應該再次重新生成一個新的Token。
如果Token保存在Cookie中,而不是服務器端的Session中,則會帶來一個新的問題。如果一個用戶打開幾個相同的頁面同時操作,當某個頁面消耗掉Token后,其它頁面的表單內保存的還是被消耗掉的那個Token,因此其它頁面的表單再次提交時,會出現Token錯誤。在這種情況下,可以考慮生成多個有效的Token,以解決多頁面共存的場景。
最后,使用Token時應該注意Token的保密性。Token如果出現在某個頁面的URL中,則可能會通過Referer的方式泄露。因此在使用Token時,應該盡量把Token放在表單中,把敏感操作由GET改為POST,以form表單或者AJAX的形式提交,可以避免Token泄露。
CSRF的Token僅僅用于對抗CSRF攻擊,當網站還同時存在XSS漏洞時,這個方案就會變得無效,因為XSS可以模擬客戶端瀏覽器執行任意操作。在XSS攻擊下,攻擊者完全可以請求頁面后,讀出該內容里的Token值,然后再構造出一個合法的請求。這個過程可以稱之為XSRF,和CSRF以示區分。
三、小結
CSRF攻擊是攻擊者利用用戶的身份操作用戶賬戶的一種攻擊方式。設計CSRF的防御方案必須先理解CSRF攻擊的原理和本質。
根據“不可預測性原則”,我們通常使用Anti CSRF Token來防御CSRF攻擊。在使用Token時,要注意Token的保密性和隨機性。
點擊劫持(ClickJacking)
1.什么是點擊劫持
點擊劫持是一種視覺上的欺騙手段,它與CSRF有異曲同工之妙,都是在用戶不之情的情況下誘使用戶完成一些動作。但是在CSRF攻擊的過程中,如果出現用戶交互的頁面,則攻擊可能無法順利完成,而點擊劫持利用的就是與用戶產生交互的頁面。
2.點擊劫持多種多樣
Flash點擊劫持
圖片覆蓋攻擊
拖拽劫持與數據竊取
觸屏劫持
3.防御點擊劫持
ClickJacking是一種視覺上的欺騙,針對傳統的ClickJacking,一般是通過禁止跨域的iframe來防范。
-
frame busting
通常可以寫一段JavaScript代碼,以禁止iframe的嵌套,這種方法叫做frame busting。比如下面這段代碼:
javascript if(top.location != location){ top.location = self.location; }
-
X-Frame-Options
因為frame busting存在被繞過的可能,所以我們需要尋找其他更好的解決方案。一個比較好的方案是使用一個HTTP頭-X-Frame-Options。
X-Frame-Options可以說是為了解決ClickJacking而生的。它有三個可選的值。
DENY——拒絕當前頁面加載任何frame頁面;
SAMEORIGIN——frame頁面的地址只能為同源域名下的頁面;
ALLOW-FROM origin——可以定義允許frame加載的頁面地址。
4.小結
ClickJacking相對于XSS與CSRF來說,因為需要誘使用戶與頁面產生交互行為,因此實施攻擊的成本更高,在網絡犯罪中比較少見。但ClickJacking在未來仍有可能被攻擊者利用,不可不察。
HTML5安全
HTML5中新增的一些標簽和屬性,使得XSS等Web攻擊產生了新的變化。
1.iframe的sandbox
在HTML5中,專門為iframe定義了一個新的屬性,叫sandbox。使用sandbox這一屬性后,<iframe>標簽加載的內容被視為一個獨立的”源“,其中的腳本將被禁止執行,表單被禁止提交,插件被禁止加載,指向其他瀏覽器對象的鏈接也會被禁止。
sandbox屬性可以通過參數來支持更精確的控制,有一下幾個值可以選擇:
allow-same-origin:允許同源訪問
allow-top-navigation:允許訪問頂層窗口
allow-forms:允許提交表單
allow-script:允許執行腳本(有的行為,即使是設置了allow-script也是不允許的,比如“彈出窗扣”)
iframe的sandbox屬性將極大地增強應用使用iframe的安全性
2.Link Types:noreferrer
標簽指定noreferrer后,瀏覽器在請求該標簽執行的地址時將不再發送Referer,這種設計是出于保護用戶敏感信息和隱私的考慮。避免通過Refer泄露一些敏感信息。(這個標簽需要開發者手動添加在頁面的標簽中)
HTTP Referer是header的一部分,當瀏覽器向Web服務器發送請求的時候,一般會帶上Referer,告訴服務器我是從哪個頁面鏈接過來的,服務器基此可以獲得一些信息用于處理。
3.Canvas的妙用
其它安全問題
1.Cross-Origin Resource Sharing
Origin Header用于標記HTTP發起的“源”,服務器通過識別瀏覽器自動帶上這個Origin Header,來判斷瀏覽器的請求是否來自一個合法的“源”。Origin Header可以用于防范CSRF,它不像Referer那么容易被偽造或者清空。
2.postMessage——跨窗口傳遞消息
postMessage允許每一個window(包括當前窗口、彈出窗口、iframes等)對象往其他的窗口發送文本信息,從未實現跨窗口的消息傳遞。并且,這個功能是不受同源策略限制的。
發送窗口負責發送事件,而接收窗口需要綁定一個“message”事件,監聽其他窗口發來的消息。如果沒有監聽這個事件,則無法接收到消息。
在使用postMessage()時,有兩個安全問題需要注意:
必要時,可以在接收窗口驗證Domain,甚至驗證URL,以防止來自非法頁面的消息。這實際上是在代碼中實現一次同源策略的驗證過程。
根據“Secure By Default”原則, 在接收窗口不應該信任任何接收到的消息,而需要對消息進行安全檢查。
3.Web Storage
Web Storage讓Web開發更加的靈活多變,它的強大功能也為XSS Payload打開方便之門,攻擊者有可能將惡意代碼保存在Web Storage中,從而實現跨頁面攻擊。