什麼是 XSS 攻擊?如何防範?

2023年2月9日

💎 加入 E+ 成長計畫 與超過 300+ 位軟體工程師一同在社群中成長,並且獲得更多的軟體工程學習資源

XSS (cross-site scripting) 是很常見的網路攻擊。身為網頁前端或後端工程師,在面試中,很常會問到 XSS 的問題,因為面試官要確定你對於 XSS 的基本概念需要有所掌握。

什麼是 XSS?

XSS 攻擊是指當某個惡意用戶,從客戶端注入攻擊腳本來達到某種目的(例如:竊取 Cookie、Session、密碼等),導致其他用戶受到波及。之所以會說是跨域 (cross-site),是因為這種攻擊方式,通常是從可信的來源發出,因此能夠繞過同源政策 (same origin policy)。舉例來說,某個用戶以合法身份進到某個網站,這時因為他是合法身份,網站認為該用戶輸入的東西是可信任的,所以當該用戶注入攻擊腳本時,網站也會認為該腳本是可信任的。

最常見的 XSS 攻擊是把 JavaScript 的腳本注入到輸入框中。例如在某個論壇網站中,惡意用戶把攻擊腳本注入到輸入框,然後變成某篇論壇貼文。這時當其他用戶進到論壇時,因為瀏覽了那篇帶有惡意腳本的貼文,所以被攻擊。

用戶可以輸入惡意的 Javascript 語法,讓系統出現問題,有興趣的可以透過這個網站來試試看。

因為 JavaScript 幾乎可以做到任何事,所以 XSS 的攻擊能做到的事情也是五花八門。舉例來說,竊取別的用戶的 cookie,然後透過拿到的 cookie 來發送請求;或者是竄改網頁內容。下面分享一個早些年直播平台 Twitch 因為防禦做得不夠完善,被惡搞的例子。這個例子就是透過 XSS 達成的。

XSS 攻擊的類型

Stored XSS

被保存在資料庫中的 Javascript 引起的攻擊稱為 Stored XSS,最常見的就是文章、留言等,因為用戶可以任意輸入內容,若沒有檢查,則 <script> 等標籤就會被視為正常的 HTML 做執行。

Reflected XSS

此類型不會被存在資料庫中,主要透過用戶發出惡意的請求,倘若後端沒有過濾而直接將結果回傳前端的話,就有可能執行到惡意的程式碼,舉例來說:

Reflected XSS
Reflected XSS

倘若用戶填完名字後,顯示的程式碼如下:

<h3> Hi, <?=$_GET['name'] ?> </h3>

則很有可能被用戶惡意填寫為:

https://websiteA/welcome?name=<script>alert(123)</script>

此種手法通常都用於釣魚、社交工程等方式誘騙用戶點入連結。

DOM-Based XSS

DOM 全名為 Document Object Model,它可以利用 Javascript 動態產生完整的網頁,不用透過後端,因此 DOM-Based XSS 是指網頁上的 Javascript 在執行過程中,沒有檢查輸入資料,使得操作 DOM 的過程中帶入了惡意程式碼。

DOM-Based XSS
DOM-Based XSS

在同一個網址上,透過 DOM 的方式直接顯示在前端頁面

<script>
  var hello = function () {
    let name = document.getElementById("name").value;
    document.getElementById("show").innerHTML = name;
  };
</script>
<h3>Hi, <span id="show"></span></h3>
<input id="name" type="text" />
<button onclick="hello();">Go</button>

因此只要將輸入的內容寫為

<img src="#" onerror="alert(123);" />

則會因為讀取不出圖片而產生錯誤,觸發 onerror ,並執行 alert(123)

此類型的攻擊,或許沒辦法直接讓用戶輸入語法,但可以搭配 Stored XSS 和 Reflected XSS 製造出內容,再藉由 Javascript 動態產生有效的 DOM 物件來執行惡意程式碼。

如何防禦 XSS?

  1. DOM-Based 防範 - 檢查輸入欄位。此攻擊需要從前端去防範,任何的輸入欄位,例如留言欄位、檔案上傳欄位、表單的欄位等,都要有跳脫的機制,讓腳本被轉換成字符串。舉例來說,如果攻擊者輸入 <script>alert(1)</script> ,我們把 < 轉成 &lt ,在畫面上依然是呈現 < 但是對程式來說,它不會被當成 HTML 標籤來解析。

  2. 確保來自使用者的腳本不會被執行。透過 CSP (content security policy) 來設定有哪些網域 (domains) 來的腳本該被瀏覽器認為是該被執行的,然後瀏覽器只執行那些該被執行的腳本。舉例來說,如果設定只有來自與網站同一個網域的腳本可被執行,那麼其他由惡意攻擊者注入的腳本,就會被認定成不該執行的,就不會被執行。

  3. Stored、Reflected 防範。這兩種都必須由後端進行防範,任何允許用戶輸入的內容都要檢查,刪除相關的關鍵字,像是 <script>onerror 等指令。


相關文章

🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們