Skip to main content

XSS 介紹與防禦方法

XSS (Cross-Site-Scripting)

攻擊者將惡意程式碼腳本(例如 HTML 與 JS)植入網站內,讓網站去執行這些惡意程式碼,以獲得機敏資料

因為會由用戶的瀏覽器來執行惡意腳本,攻擊者可擷取使用者的私密網頁內容、對談或是透過擷取 Cookie 或 Session 資料而假冒使用者為合法使用者等

心態:不要全然信任使用者的 input,包含表單、URL 輸入、request

反射型 XSS

網站上某些地方會 自動響應 使用者的 query string 或是 request 參數,例如「您搜尋的是 __ 」,這些內容如果沒有進行轉義處理,容易被植入惡意程式碼,讓瀏覽器執行

// 例如某個網站具有搜索功能, 藉由 query string 接收用戶的搜尋關鍵字 //
https://xxx.com/search?query=123 // 網站的 HTML 內容根據 query string 響應關鍵字
<p>您搜尋的是: 123</p>

// 如果伺服器不對這些參數進行轉義處理, 駭客可以藉由這個途徑注入惡意程式碼,
讓網站伺服器執行惡意程式碼內容 // 例如 // https://xxx.com/search?query=<img
src="empty.png"
onerror="alert('xss')"
/>

// 伺服器就會執行 alert 裡面的內容
<p>您搜尋的是: <img src="empty.png" onerror="alert('xss')" /></p>

// 如果有用户 request 含有惡意程式碼的 URL, 駭客提供的腳本會在該用戶的瀏覽器執行
// 可能透過釣魚的方式或是郵件傳送給被害人
  1. 以社交工程誘惑使用者使用者點擊有惡意程式碼的 URL
  2. 因為 URL 通常看起來很詭異,所以攻擊者通常會使用短網址服務或 HTML Encoder 的方式嘗試欺騙用戶

儲存型 XSS

XSS 的惡意程式碼會被儲存在伺服器的資料庫當中(例如論壇留言、部落格貼文),如果貼文內容藏有惡意程式碼,每次只要有人點開這篇文章,就又會被該用戶的瀏覽器執行一次

// 駭客將惡意程式碼作為留言提交, 伺服器也沒進行轉義處理的話, 就會被攻擊
<textarea>
<img src="empty.png" onerror ="alert('xss')">
</textarea>
// 駭客提供的腳本會在所有訪問該留言頁面的用戶瀏覽器執行

DOM-based XSS

網頁上的 JavaScript 的 function 沒有詳細檢查使用者的 input,就以不安全的方式直接操作 DOM,例如 innerHTML 被植入惡意腳本

<script>
let createText = function () {
let name = document.querySelector("#name").value;
document.querySelector("#showName").innerHTML = name;
};
</script>

<h3>Hi, <span id="showName"></span></h3>
<input type="text" id="name" />
<button onclick="createText()">Say hi</button>

// 如果 input 輸入 " <img src="#" onerror="alert(123)" />" 會建立新的DOM
並執行惡意腳本

但是使用者不太可能傻傻自己輸入這些惡意腳本,所以或許搭配前面兩種方式來達到這效果

責任歸屬

  • 反射型: 主要由後端負責,因為後端會是接收 query string 並自動響應結果的主要處理者
  • 儲存型: 主要也是由後端負責,因為送入資料庫的貼文內容都要進行檢查,但或許前端可以在輸入內容進行基本防範
  • DOM-based: 前端負責,因為操作 DOM 是前端 JS 的範疇

但是正確的心態是,不論是前後端都應假設輸入是惡意且不可信任的

怎麼防範

使用者輸入的內容都需要檢查,刪除所有「<script>」、「onerror=」及其他任何可能執行代碼的字串

<>"'& 這些字串進行轉義,如 &lt;, &gt;,瀏覽器會把他們正確渲染成字串,但不諱當成程式碼的一部分

不要將使用者的輸入放入 註解、屬性名稱、標籤名稱 等,因為這些位置都能將字符串作為程式碼運行

React 與 XSS

React 在渲染 HTML 內容和 DOM 屬性時,會將 <>"'& 自動進行轉義

而在 JSX 語法中,Babel 會編譯 JSX 變成  React.createElement(),React 在進行渲染的時候也會對 element 進行檢查,防止透過特殊的 chidrenNode 來進行 XSS 攻擊

React 可能會有漏洞的地方

dangerouslySetInnerHTML 顧名思義就是危險,可能會產生等同於 DOM-based XSS 的 innerHTML 漏洞,平時開發最好避免

Reference

浅谈 React 中的 XSS 攻击

【網頁安全】給網頁開發新人的 XSS 攻擊介紹與防範

零基礎資安系列(二)-認識 XSS(Cross-Site Scripting)