什麼是XSSjavascript
XSS(Cross Site Scripting),跨站腳本攻擊,是一種容許攻擊者在另一個用戶的瀏覽器中執行惡意代碼腳本的腳本注入式攻擊。原本縮小應該是CSS,但爲了和層疊樣式(Cascading Style Sheet,CSS)有所區分,故稱XSS。java
對於攻擊者來講,可以讓受害者瀏覽器執行惡意代碼的惟一方式,就是把代碼注入到受害者從網站下載的網頁中。git
xss攻擊的種類github
一、持續型XSS攻擊:惡意腳原本源於網站的數據庫數據庫
咱們來看這種攻擊的一個場景後端
一、攻擊者經過評論表單提交將<script>alert(‘aaa’)</script>提交到網站瀏覽器
二、網站後端對提交的評論數據不作任何操做,直接存儲到數據庫中安全
三、其餘用戶訪問正常訪問網站,而且須要請求網站的評論數據服務器
四、網站後端會從數據庫中取出數據,直接返回給用戶cookie
五、用戶獲得頁面後,直接運行攻擊者提交的代碼<script>alert(‘aaa’)</script>,全部用戶都會在網頁中彈出aaa的彈窗
這種攻擊方式惡意代碼會被存儲在數據庫中,其餘用戶在正常訪問的狀況下,也有會被攻擊,影響的範圍比較大
二、反射型XSS攻擊:惡意腳原本源於受害者的請求
在一個反射型XSS攻擊中,惡意文本屬於受害者發送給網站的請求中的一部分。隨後網站又把惡意文本包含進用於響應用戶的返回頁面中,發還給用戶。
咱們來看下面這個場景
一、用戶誤點開了帶攻擊的url :http://xxx?keyword=<script>alert('aaa')</script>
二、網站給受害者的返回中包含了來自URL的的惡意文本
三、用戶的瀏覽器收到文本後執行頁面,會在網頁中彈窗aaa
反射型的攻擊須要用戶主動的去訪問帶攻擊的連接,攻擊者能夠經過郵件或者短信的形式,誘導受害者點開連接。若是攻擊者配合短連接URL,攻擊成功的機率會更高
三、基於DOM的XSS攻擊
基於DOM的XSS攻擊是反射型攻擊的變種。服務器返回的頁面是正常的,只是咱們在頁面執行js的過程當中,會把攻擊代碼植入到頁面中
下面展現的是這種攻擊的場景
1、用戶誤點開了帶攻擊的url :http://xxx?name=<script>alert('aaa')</script>
2、網站給受害者的返回中正常的網頁
3、用戶的瀏覽器收到文本後執行頁面合法腳本,這時候頁面惡意腳本會被執行,會在網頁中彈窗aaa
這種攻擊方式發生在咱們合法的js執行中,服務器沒法檢測咱們的請求是否有攻擊的危險
攻擊的危害
攻擊者把代碼注入進了訪問的頁面,因此惡意腳本都在網站的上下文環境中執行,這就意味着惡意代碼被當作網站提供的正常腳本同樣對待:他有權訪問頁面與網站的關鍵數據(好比cookie),瀏覽器會認爲他是網站的合法部分,容許他作任何事情。好比拿到用戶的cookie信息,而後傳送到攻擊者本身的服務器,從cookie中提取敏感信息,拿到用戶的登陸信息,或者攻擊者能夠經過修改DOM在頁面上插入一個假的登錄框,也能夠把表單的`action`屬性指向他本身的服務器地址,而後欺騙用戶提交本身的敏感信息。
如何防止攻擊
XSS攻擊其實就是代碼的注入。用戶的輸入被編譯成惡意的程序代碼。因此,爲了防範這一類代碼的注入,須要確保用戶輸入的安全性。對於攻擊驗證,咱們能夠採用如下兩種措施:
一、編碼,就是轉義用戶的輸入,把用戶的輸入解讀爲數據而不是代碼
二、校驗,對用戶的輸入及請求都進行過濾檢查,如對特殊字符進行過濾,設置輸入域的匹配規則等。
對於驗證輸入,咱們既能夠在服務端驗證,也能夠在客戶端驗證
對於持久性和反射型攻擊,服務端的驗證是必須的,服務端支付的任何語言都可以作到
而對於基於DOM的XSS攻擊,驗證輸入在客戶端必須執行,由於從服務端來講,全部發出的頁面內容是正常的,只是在客戶端js代碼執行的過程當中才發生可攻擊
可是對於各類攻擊,咱們最好作到客戶端和服務端都進行處理。這裏,咱們主要討論的是客戶端的驗證,至於服務端如何過濾驗證,能夠查看其它資料
編碼
在客戶端使用javascript對用戶輸入進行編碼時,有一些內置的方法和屬性可以自動感知對上下文的狀況下自動對全部的數據進行編碼
下表就是一些自動編碼的方式:
這些內置的方法會對用戶的輸入自動編碼
可是對於用戶的自動輸入進行編碼也會有弊端,惡意文本也有可能插入進上下文中。看下面的例子:
document.querySelector(‘a’).href = 「javascript:alert(‘aaa’)」
雖然給href屬性的時候會被自動編碼,可是這已不能組織攻擊者嵌入執行腳本。
另外,若是需求是可讓用戶自定義頁面的代碼,對輸入進行編碼也不是一個很好的解決方案。編碼會把用戶的輸入當成純文本輸出,這樣就跟需求不符了。
針對這樣的狀況,咱們只能對文本進行校驗了。
校驗
校驗是一種過濾用戶輸入以致於讓代碼中惡意部分被移除的行爲。校驗都是經過必定的經驗和規則,對用戶的輸入進行匹配,過濾,去除掉存在攻擊風險的部分。咱們能夠經過黑名單的方式和白名單的方式來設置咱們的規則
好比: 咱們在檢測a 標籤的時候,只要輸入帶入javascript字段的時候,咱們就認爲非法,javascript字段就成爲咱們黑名單的匹配規則
同時,咱們能夠採用另一種檢測方式,只要a標籤有href屬性的時候,咱們只容許http協議的連接,若是是咱們經過,不是就認爲非法,這裏就須要咱們創建一張白名單的匹配規則
白名單和黑名單均可以對數據進行過濾,可是黑名單會隨着攻擊方式的變化而改變,對於規則的使用,白名單更具長效性。因此對於匹配規則最好採用白名單的機制
下面有一個類庫是針對防XSS攻擊的,能夠引入到咱們平常項目中使用:
https://github.com/leizongmin/js-xss
Content Security Policy(CSP)
只使用驗證輸入來防止XSS攻擊的劣勢在於即便存在一絲的漏洞也會使得你的網站遭到攻擊。最近的一個被稱爲Content Security Policy(CSP)的標準可以減小這個風險。
CSP對你用於瀏覽頁面的瀏覽器作出了限制,以確保它只能從可信賴來源下載的資源。*資源*能夠是腳本,樣式,圖片,或者其餘被頁面引用的文件。這意味着即便攻擊者成功的在你的網站中注入了惡意內容,CSP也能免於它被執行。
CSP也是採用白名單的方式來匹配網頁的解析和代碼的執行,只不過,執行的層次上升到了瀏覽器的高度,對於CSP如何設置,能夠參考如下的文章:
https://mp.weixin.qq.com/s/Pz7gS9_7J16wZGrR8zgR8g
總結:
在平常的開發過程當中,咱們對於用戶的輸入嵌入到頁面中要格外當心,根據嵌入內容的上下文,採起不一樣的防範策略,提升咱們頁面的安全性