天天看點

Web 安全漏洞之 XSS 攻擊

Web 安全漏洞之 XSS 攻擊

編者說:作為JS系工程師接觸最多的漏洞我想就是 XSS 漏洞了,然鵝并不是所有的同學對其都有一個清晰的認識。今天我們請來了@盧士傑 同學為我們分享他眼中的 XSS 漏洞攻擊,希望能幫助到大家。

什麼是 XSS 攻擊

XSS(Cross-Site Scripting)又稱跨站腳本,XSS的重點不在于跨站點,而是在于腳本的執行。XSS是一種經常出現在 Web 應用程式中的計算機安全漏洞,是由于 Web 應用程式對使用者的輸入過濾不足而産生的。

常見的 XSS 攻擊有三種:反射型、DOM-based 型、存儲型。 其中反射型、DOM-based 型可以歸類為非持久型 XSS 攻擊,存儲型歸類為持久型 XSS 攻擊。

1.反射型

反射型 XSS 一般是攻擊者通過特定手法(如電子郵件),誘使使用者去通路一個包含惡意代碼的 URL,當受害者點選這些專門設計的連結的時候,惡意代碼會直接在受害者主機上的浏覽器執行。

對于通路者而言是一次性的,具體表現在我們把我們的惡意腳本通過 URL 的方式傳遞給了伺服器,而伺服器則隻是不加處理的把腳本“反射”回通路者的浏覽器而使通路者的浏覽器執行相應的腳本。反射型 XSS 的觸發有後端的參與,要避免反射性 XSS,必須需要後端的協調,後端解析前端的資料時首先做相關的字串檢測和轉義處理。

此類 XSS 通常出現在網站的搜尋欄、使用者登入口等地方,常用來竊取用戶端 Cookies 或進行釣魚欺騙。

整個攻擊過程大約如下:

Web 安全漏洞之 XSS 攻擊

2.DOM-based 型

用戶端的腳本程式可以動态地檢查和修改頁面内容,而不依賴于伺服器端的資料。例如用戶端如從 URL 中提取資料并在本地執行,如果使用者在用戶端輸入的資料包含了惡意的 JavaScript 腳本,而這些腳本沒有經過适當的過濾和消毒,那麼應用程式就可能受到 DOM-based XSS 攻擊。需要特别注意以下的使用者輸入源 

document.URL

、 

location.hash

location.search

document.referrer

 等。

Web 安全漏洞之 XSS 攻擊

3.存儲型

攻擊者事先将惡意代碼上傳或儲存到漏洞伺服器中,隻要受害者浏覽包含此惡意代碼的頁面就會執行惡意代碼。這就意味着隻要通路了這個頁面的訪客,都有可能會執行這段惡意腳本,是以儲存型XSS的危害會更大。

存儲型 XSS 一般出現在網站留言、評論、部落格日志等互動處,惡意腳本存儲到用戶端或者服務端的資料庫中。

Web 安全漏洞之 XSS 攻擊

XSS 攻擊的危害

XSS 可以導緻:

1. 攻擊劫持通路;

2. 盜用 cookie 實作無密碼登入;

3. 配合 csrf 攻擊完成惡意請求;

4. 使用 js 或 css 破壞頁面正常的結構與樣式等;

防禦方法

1. XSS 防禦之 HTML 編碼

應用範圍:将不可信資料放入到 HTML 标簽内(例如div、span等)的時候進行HTML編碼。

編碼規則:将 & < > " ' / 轉義為實體字元(或者十進制、十六進制)。

示例代碼:

  1.  function encodeForHTML(str, kwargs){

  2.    return ('' + str)

  3.      .replace(/&/g, '&')

  4.      .replace(/</g, '<')     // DEC=> < HEX=> < Entity=> <

  5.      .replace(/>/g, '>')

  6.      .replace(/"/g, '"')

  7.      .replace(/'/g, ''')   // ' 不推薦,因為它不在HTML規範中

  8.      .replace(/\//g, '/');

  9.  };

HTML 有三種編碼表現方式:十進制、十六進制、命名實體。例如小于号(<)可以編碼為 "十進制> <", "十六進制=> <", "命名實體=> <" 三種方式。對于單引号(')由于實體字元編碼方式不在 HTML 規範中,是以此處使用了十六進制編碼。

2. XSS 防禦之 HTML Attribute 編碼

應用範圍:将不可信資料放入 HTML 屬性時(不含src、href、style 和事件處理屬性),進行 HTML Attribute 編碼

編碼規則:除了字母數字字元以外,使用 HH;(或者可用的命名實體)格式來轉義ASCII值小于256所有的字元

  1.  function encodeForHTMLAttibute(str, kwargs){

  2.    let encoded = '';

  3.    for(let i = 0; i < str.length; i++) {

  4.      let ch = hex = str[i];

  5.      if (!/[A-Za-z0-9]/.test(str[i]) && str.charCodeAt(i) < 256) {

  6.        hex = '&#x' + ch.charCodeAt(0).toString(16) + ';';

  7.      }

  8.      encoded += hex;

  9.    }

  10.    return encoded;

  11.  };

3. XSS 防禦之 JavaScript 編碼

作用範圍:将不可信資料放入事件處理屬性、JavaScirpt值時進行 JavaScript 編碼

編碼規則:除字母數字字元外,請使用xHH格式轉義ASCII碼小于256的所有字元

  1.  function encodeForJavascript(str, kwargs) {

  2.    let encoded = '';

  3.    for(let i = 0; i < str.length; i++) {

  4.      let cc = hex = str[i];

  5.      if (!/[A-Za-z0-9]/.test(str[i]) && str.charCodeAt(i) < 256) {

  6.        hex = '\\x' + cc.charCodeAt().toString(16);

  7.      }

  8.      encoded += hex;

  9.    }

  10.    return encoded;

  11.  };

4. XSS 防禦之 URL 編碼

作用範圍:将不可信資料作為 URL 參數值時需要對參數進行 URL 編碼

編碼規則:将參數值進行 encodeURIComponent 編碼

  1.  function encodeForURL(str, kwargs){

  2.    return encodeURIComponent(str);

  3.  };

5. XSS 防禦之 CSS 編碼

作用範圍:将不可信資料作為 CSS 時進行 CSS 編碼

編碼規則:除了字母數字字元以外,使用XXXXXX格式來轉義ASCII值小于256的所有字元

  1.  function encodeForCSS (attr, str, kwargs){

  2.    let encoded = '';

  3.    for (let i = 0; i < str.length; i++) {

  4.      let ch = str.charAt(i);

  5.      if (!ch.match(/[a-zA-Z0-9]/) {

  6.        let hex = str.charCodeAt(i).toString(16);

  7.        let pad = '000000'.substr((hex.length));

  8.        encoded += '\\' + pad + hex;

  9.      } else {

  10.        encoded += ch;

  11.      }

  12.    }

  13.    return encoded;

  14.  };

後記

在任何時候使用者的輸入都是不可信的。對于 HTTP 參數,理論上都要進行驗證,例如某個字段是枚舉類型,其就不應該出現枚舉以為的值;對于不可信資料的輸出要進行相應的編碼;此外 

httpOnly

CSP

X-XSS-Protection

Secure Cookie

等也可以起到有效的防護。

XSS 漏洞有時比較難發現,所幸當下React、Vue等架構都從架構層面引入了 XSS 防禦機制,一定程度上解放了我們的雙手。

但是作為開發人員依然要了解 XSS 基本知識、于細節處避免制造 XSS 漏洞。架構是輔助,我們仍需以人為本,規範開發習慣,提高 Web 前端安全意識。

參考文檔

 ●  http://www.qa-knowhow.com/?p=1467 

 ●  https://brajeshwar.github.io/entities/ 

 ●  https://excess-xss.com/ 

 ●  https://github.com/chrisisbeef/jquery-encoder

原文釋出時間為:2018-11-23

本文來自雲栖社群合作夥伴“

前端大學

”,了解相關資訊可以關注“

”。

繼續閱讀