前端安全之 XSS 綜述

語言: CN / TW / HK

theme: github

概述

跨站點指令碼 (XSS) 攻擊是一種注入,其中惡意指令碼被注入到其他良性和受信任的網站中。當攻擊者使用 Web 應用程式將惡意程式碼(通常以瀏覽器端指令碼的形式)傳送給不同的終端使用者時,就會發生 XSS 攻擊。允許這些攻擊成功的缺陷非常普遍,並且發生在 Web 應用程式在其生成的輸出中使用來自使用者的輸入而不對其進行驗證或編碼的任何地方

攻擊者可以使用 XSS 向毫無戒心的使用者傳送惡意指令碼。終端使用者的瀏覽器無法知道該指令碼不應被信任,並將執行該指令碼。因為它認為指令碼來自受信任的來源,所以惡意指令碼可以訪問瀏覽器保留並與該站點一起使用的任何 cookie、會話令牌或其他敏感資訊。這些指令碼甚至可以重寫 HTML 頁面的內容。

使用 SSL (https) 的網站不會比未加密的網站更受保護。Web 應用程式的工作方式與以前相同,只是攻擊發生在加密連線中。人們通常認為,因為他們看到瀏覽器上的鎖就意味著一切都是安全的。事實並非如此。

一個經典場景

當 Web 應用程式從使用者那裡收集惡意資料時,就會發生跨站指令碼(也稱為 XSS)。資料通常以超連結的形式收集,其中包含惡意內容。使用者很可能會從另一個網站、即時訊息或只是閱讀網路板或電子郵件訊息中單擊此連結。通常,攻擊者會以 HEX(或其他編碼方法)對指向站點的連結的惡意部分進行編碼,這樣當用戶點選請求時,請求就不會那麼可疑了。Web 應用程式收集資料後,它會為使用者建立一個輸出頁面,其中包含最初發送給它的惡意資料,但以某種方式使其顯示為來自網站的有效內容。許多流行的留言簿和論壇程式允許使用者提交嵌入了 html 和 javascript 的帖子。例如,如果我以“john”的身份登入並閱讀了“joe”傳送的包含惡意 javascript 的訊息,那麼“joe”可能會通過閱讀他的公告欄帖子來劫持我的會話。

攻擊型別

儲存型 XSS 攻擊

儲存攻擊是將注入的指令碼永久儲存在目標伺服器上的攻擊,例如資料庫、訊息論壇、訪問者日誌、評論欄位等。然後受害者在請求儲存時從伺服器檢索惡意指令碼資訊。儲存型 XSS 有時也稱為 Persistent 或 Type-I XSS。

```JavaScript // 某個評論頁,能檢視使用者評論。 // 攻擊者將惡意程式碼當做評論提交,伺服器沒對資料進行轉義等處理 // 評論輸入:

// 則攻擊者提供的指令碼將在所有訪問該評論頁的使用者瀏覽器執行 ```

反射型 XSS 攻擊

反射式攻擊是指注入的指令碼從 Web 伺服器反射出來的攻擊,例如在錯誤訊息、搜尋結果或任何其他響應中,其中包括作為請求的一部分發送到伺服器的部分或全部輸入。反射攻擊通過其他途徑傳遞給受害者,例如在電子郵件訊息中或在其他網站上。當用戶被誘騙點選惡意連結、提交特製表單,甚至只是瀏覽到惡意網站時,注入的程式碼就會傳播到易受攻擊的網站,從而將攻擊反射回使用者的瀏覽器。然後瀏覽器執行程式碼,因為它來自“受信任的”伺服器。反射型 XSS 有時也稱為非永續性或 II 型 XSS。

```JavaScript // 某網站具有搜尋功能,該功能通過 URL 引數接收使用者提供的搜尋詞: https://xxx.com/search?query=123 // 伺服器在對此 URL 的響應中回顯提供的搜尋詞:

您搜尋的是: 123

// 如果伺服器不對資料進行轉義等處理,則攻擊者可以構造如下連結進行攻擊: https://xxx.com/search?query= // 該 URL 將導致以下響應,並執行 alert('xss'):

您搜尋的是:

// 如果有使用者請求攻擊者的 URL ,則攻擊者提供的指令碼將在使用者的瀏覽器中執行。 ```

DOM 型 XSS

  1. 攻擊者構造出特殊的 URL,其中包含惡意程式碼。
  2. 使用者開啟帶有惡意程式碼的 URL。
  3. 使用者瀏覽器接收到響應後解析執行,前端 JavaScript 取出 URL 中的惡意程式碼並執行。
  4. 惡意程式碼竊取使用者資料併發送到攻擊者的網站,或者冒充使用者的行為,呼叫目標網站介面執行攻擊者指定的操作。

DOM 型 XSS 跟前兩種 XSS 的區別:DOM 型 XSS 攻擊中,取出和執行惡意程式碼由瀏覽器端完成,屬於前端 JavaScript 自身的安全漏洞,而其他兩種 XSS 都屬於服務端的安全漏洞。

預防 DOM 型攻擊 ⛳

DOM 型 XSS 攻擊,實際上就是網站前端 JavaScript 程式碼本身不夠嚴謹,把不可信的資料當作程式碼執行了。

在使用 .innerHTML、.outerHTML、document.write() 時要特別小心,不要把不可信的資料作為 HTML 插到頁面上,而應儘量使用 .textContent、.setAttribute() 等。

如果用 Vue/React 技術棧,並且不使用 v-html/dangerouslySetInnerHTML 功能,就在前端 render 階段避免 innerHTML、outerHTML 的 XSS 隱患。

DOM 中的內聯事件監聽器,如 location、onclick、onerror、onload、onmouseover 等,\ 標籤的 href 屬性,JavaScript 的 eval()、setTimeout()、setInterval() 等,都能把字串作為程式碼執行。如果不可信的資料拼接到字串中傳遞給這些 API,很容易產生安全隱患,請務必避免。

REFERENCE

  1. Vue 安全指導
  2. html5 安全備忘清單
  3. Cross Site Scripting (XSS)
  4. The Cross-Site Scripting (XSS) FAQ
  5. 淺談 React 中的 XSS 攻擊
  6. 美團-前端安全系列(一):如何防止XSS攻擊?
  7. 一款 XSS 遊戲地址 🎮
「其他文章」