【前端安全】JavaScript防XSS攻擊


什么是XSS

XSSCross Site Scripting),跨站腳本攻擊,是一種允許攻擊者在另外一個用戶的瀏覽器中執行惡意代碼腳本的腳本注入式攻擊。本來縮小應該是CSS,但為了和層疊樣式(Cascading Style Sheet,CSS)有所區分,故稱XSS

對於攻擊者來說,能夠讓受害者瀏覽器執行惡意代碼的唯一方式,就是把代碼注入到受害者從網站下載的網頁中。

xss攻擊的種類

1、持續型XSS攻擊:惡意腳本來源於網站的數據庫

我們來看這種攻擊的一個場景

 

1、攻擊者通過評論表單提交將<script>alert(‘aaa’)</script>提交到網站

2、網站后端對提交的評論數據不做任何操作,直接存儲到數據庫中

3、其他用戶訪問正常訪問網站,並且需要請求網站的評論數據

4、網站后端會從數據庫中取出數據,直接返回給用戶

5、用戶得到頁面后,直接運行攻擊者提交的代碼<script>alert(‘aaa’)</script>,所有用戶都會在網頁中彈出aaa的彈窗

這種攻擊方式惡意代碼會被存儲在數據庫中,其他用戶在正常訪問的情況下,也有會被攻擊,影響的范圍比較大

2、反射型XSS攻擊:惡意腳本來源於受害者的請求

在一個反射型XSS攻擊中,惡意文本屬於受害者發送給網站的請求中的一部分。隨后網站又把惡意文本包含進用於響應用戶的返回頁面中,發還給用戶。

我們來看下面這個場景

 

1、用戶誤點開了帶攻擊的url :http://xxx?keyword=<script>alert('aaa')</script>

2、網站給受害者的返回中包含了來自URL的的惡意文本

3、用戶的瀏覽器收到文本后執行頁面,會在網頁中彈窗aaa

反射型的攻擊需要用戶主動的去訪問帶攻擊的鏈接,攻擊者可以通過郵件或者短信的形式,誘導受害者點開鏈接。如果攻擊者配合短鏈接URL,攻擊成功的概率會更高

3、基於DOMXSS攻擊

基於DOMXSS攻擊是反射型攻擊的變種。服務器返回的頁面是正常的,只是我們在頁面執行js的過程中,會把攻擊代碼植入到頁面中

下面展示的是這種攻擊的場景

 

1、用戶誤點開了帶攻擊的url :http://xxx?name=<script>alert('aaa')</script>

2、網站給受害者的返回中正常的網頁

3、用戶的瀏覽器收到文本后執行頁面合法腳本,這時候頁面惡意腳本會被執行,會在網頁中彈窗aaa

這種攻擊方式發生在我們合法的js執行中,服務器無法檢測我們的請求是否有攻擊的危險

攻擊的危害

攻擊者把代碼注入進了訪問的頁面,所以惡意腳本都在網站的上下文環境中執行,這就意味着惡意代碼被當做網站提供的正常腳本一樣對待:他有權訪問頁面與網站的關鍵數據(比如cookie,瀏覽器會認為他是網站的合法部分,允許他做任何事情。比如拿到用戶的cookie信息,然后傳送到攻擊者自己的服務器,從cookie中提取敏感信息,拿到用戶的登錄信息,或者攻擊者可以通過修改DOM在頁面上插入一個假的登陸框,也可以把表單的`action`屬性指向他自己的服務器地址,然后欺騙用戶提交自己的敏感信息。

如何防止攻擊

XSS攻擊其實就是代碼的注入。用戶的輸入被編譯成惡意的程序代碼。所以,為了防范這一類代碼的注入,需要確保用戶輸入的安全性。對於攻擊驗證,我們可以采用以下兩種措施:

1、編碼,就是轉義用戶的輸入,把用戶的輸入解讀為數據而不是代碼

2、校驗,對用戶的輸入及請求都進行過濾檢查,如對特殊字符進行過濾,設置輸入域的匹配規則等

對於驗證輸入,我們既可以在服務端驗證,也可以在客戶端驗證

對於持久性和反射型攻擊,服務端的驗證是必須的,服務端支付的任何語言都能夠做到

而對於基於DOMXSS攻擊,驗證輸入在客戶端必須執行,因為從服務端來說,所有發出的頁面內容是正常的,只是在客戶端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 PolicyCSP)的標准能夠減少這個風險。

CSP對你用於瀏覽頁面的瀏覽器做出了限制,以確保它只能從可信賴來源下載的資源。*資源*可以是腳本,樣式,圖片,或者其他被頁面引用的文件。這意味着即使攻擊者成功的在你的網站中注入了惡意內容,CSP也能免於它被執行。

CSP也是采用白名單的方式來匹配網頁的解析和代碼的執行,只不過,執行的層次上升到了瀏覽器的高度,對於CSP如何設置,可以參考以下的文章:

https://mp.weixin.qq.com/s/Pz7gS9_7J16wZGrR8zgR8g

總結:

在日常的開發過程中,我們對於用戶的輸入嵌入到頁面中要格外小心,根據嵌入內容的上下文,采取不同的防范策略,提高我們頁面的安全性


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM