大部分的人都知道不要亂點來路不明的網址,因為可能會造成資料外洩。 但大家有沒有想過,為什麼點了一個連結就可能造成危害?

其實問題不在於『點連結』這個行為本身,而是網站沒有對連結中的內容做過濾,才讓惡意程式碼有機會被執行。

因為攻擊者可能會利用網站的漏洞,在網站中插入惡意程式碼, 當使用者打開頁面時,這些程式碼就會在瀏覽器中被執行。

而這種常見的攻擊方式之一,就是 XSS

在深入了解之前,我們先簡單看看 XSS 是什麼

XSS 全名 Cross Site Scripting (跨網站指令碼),是一種利用網站漏洞,在其他使用者瀏覽器中執行惡意 JavaScript 的攻擊方式。

簡單來說就是:

攻擊者把惡意程式碼「偷偷塞進網站」,當其他使用者打開頁面時,瀏覽器就會幫忙執行這段程式碼。因為 JavaScript 是在瀏覽器端執行的,所以使用者通常不會察覺自己已經被攻擊。

例如你在某個網站留言,輸入了一段看似普通的文字,但如果網站沒有做好防護,攻擊者可能會把 JavaScript 程式碼藏在留言裡。

當其他使用者瀏覽這篇留言時,瀏覽器就會執行這段程式碼。

💡為什麼是 XSS 而不是 CSS? XSS 的全名是 Cross-Site Scripting,照理說縮寫應該是 CSS 才對, 但因為 CSS (Cascading Style Sheets)早就已經存在,為了避免混淆,安全領域的人把 Cross 的 C 改成 X(代表 Cross),於是就變成 XSS 了!

📌 XSS 常見的三種類型

XSS 大致可以分成三種攻擊方式:

1. 反射型 XSS ( Reflected XSS )

這是 最常見的一種 XSS 攻擊,通常是透過 URL 參數 來發動。

簡單的流程大概是:

  1. 攻擊者製作一個帶有惡意 script 的網址
  2. 想辦法讓使用者點擊
  3. 網站把 URL 參數直接顯示在頁面上
  4. 瀏覽器就會執行其中的 JavaScript

例如:

https://example.com/search?q=<script>alert('XSS')</script>

如果網站沒有過濾這段內容,script 就會被執行。

2. 儲存型 XSS ( Stored XSS )

Stored XSS 通常 比 Reflected XSS 更危險,因為惡意程式碼會被存進資料庫裡,只要有人點擊被感染的頁面就會被觸發。

常出現在:留言區、討論區、使用者個人資料和文章內容等。

例如:

攻擊者在某個沒有過濾網頁內容的留言區輸入:

<script>stealCookie()</script>

只要其他使用者打開留言區,這段 script 就會在他們的瀏覽器中執行。

3. DOM 型 XSS ( Dom-based XSS )

DOM 型比較特別,它不一定跟後端有關, 漏洞通常出現在前端 JavaScript 操作 DOM 的方式

例如這段程式碼:

const params = new URLSearchParams(location.search);
document.body.innerHTML = params.get("msg");

如果網址是 :

?msg=<script>alert('XSS')</script>

因為使用了 innerHTML 瀏覽器就會把這段 script 當作 HTML 解析並執行。

所以DOM 型 XSS 其實是「前端程式碼造成的安全問題」。

為什麼要 XSS 攻擊?可以得到什麼?

XSS 的目的通常是 取得使用者資訊或冒用身分,例如:

  1. 取得 Cookie

攻擊者可以透過 JavaScript 讀取 cookie,如果網站沒有設定 HttpOnly, 攻擊者就可能拿到 session cookie,然後:

  • 偽裝成該使用者登入
  • 存取私人資料
  • 進行未授權操作

2. 冒用使用者身分操作網站

  • 發送訊息
  • 修改帳號資料
  • 發布內容
  • 進行交易

因為操作是從使用者的瀏覽器發出,網站通常很難分辨這是不是攻擊。

3. 釣魚或導向惡意網站

  • 修改頁面內容
  • 插入假的登入表單
  • 導向釣魚網站

有些情況下,使用者甚至完全不知道自己被攻擊了。

如何避免 XSS ?

要有效的避免 XSS 通常需要 前端跟後端一起處理

  1. 前端避免使用 innerHTML

盡量用 textContent 而不是 innerHTML

例如:

// 比較安全
element.textContent = userInput;
//可能有風險
element.innerHTML = userInput;

因為 textContent 只會把內容當成 純文字,不會解析 HTML。

2. 後端做輸入驗證 ( Validation)

例如限制:

  • email格式
  • 數字
  • 特定字元

避免惡意 HTML 被送進系統。

3. 對輸出內容做過濾 (Sanitization)

在輸出到頁面之前,把危險的內容移除,例如:

  • <script>
  • onerror
  • javascript:

通常會使用專門的 Sanitizer library 來處理。

4. 使用額外的安全機制

例如:

  • HttpOnly Cookie
  • Content Security Policy (CSP)
  • HTML Encoding

結言:

在深入了解 XSS 之前,我以為釣魚信件的惡意程式碼是在「點擊連結的那一瞬間」就會被執行,但其實工程師在開發時只要遵守以下幾個原則,就不用太擔心 XSS 攻擊!

  • 不隨意使用 innerHTML
  • 對輸入做驗證
  • 對輸出做過濾

簡單來說,XSS 的核心問題其實只有一個: 網站信任了不該信任的輸入。

只要使用者輸入的內容沒有經過適當的驗證與過濾,就可能被當成程式碼執行。

參考資料:

如果有理解錯誤的地方歡迎指正👏🏻