大部分的人都知道不要亂點來路不明的網址,因為可能會造成資料外洩。 但大家有沒有想過,為什麼點了一個連結就可能造成危害?
其實問題不在於『點連結』這個行為本身,而是網站沒有對連結中的內容做過濾,才讓惡意程式碼有機會被執行。
因為攻擊者可能會利用網站的漏洞,在網站中插入惡意程式碼, 當使用者打開頁面時,這些程式碼就會在瀏覽器中被執行。
而這種常見的攻擊方式之一,就是 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 參數 來發動。
簡單的流程大概是:
- 攻擊者製作一個帶有惡意 script 的網址
- 想辦法讓使用者點擊
- 網站把 URL 參數直接顯示在頁面上
- 瀏覽器就會執行其中的 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 的目的通常是 取得使用者資訊或冒用身分,例如:
- 取得 Cookie
攻擊者可以透過 JavaScript 讀取 cookie,如果網站沒有設定 HttpOnly, 攻擊者就可能拿到 session cookie,然後:
- 偽裝成該使用者登入
- 存取私人資料
- 進行未授權操作
2. 冒用使用者身分操作網站
- 發送訊息
- 修改帳號資料
- 發布內容
- 進行交易
因為操作是從使用者的瀏覽器發出,網站通常很難分辨這是不是攻擊。
3. 釣魚或導向惡意網站
- 修改頁面內容
- 插入假的登入表單
- 導向釣魚網站
有些情況下,使用者甚至完全不知道自己被攻擊了。
如何避免 XSS ?
要有效的避免 XSS 通常需要 前端跟後端一起處理。
- 前端避免使用 innerHTML
盡量用 textContent 而不是 innerHTML
例如:
// 比較安全
element.textContent = userInput;
//可能有風險
element.innerHTML = userInput;因為 textContent 只會把內容當成 純文字,不會解析 HTML。
2. 後端做輸入驗證 ( Validation)
例如限制:
- email格式
- 數字
- 特定字元
避免惡意 HTML 被送進系統。
3. 對輸出內容做過濾 (Sanitization)
在輸出到頁面之前,把危險的內容移除,例如:
<script>onerrorjavascript:
通常會使用專門的 Sanitizer library 來處理。
4. 使用額外的安全機制
例如:
HttpOnly CookieContent Security Policy (CSP)- HTML Encoding
結言:
在深入了解 XSS 之前,我以為釣魚信件的惡意程式碼是在「點擊連結的那一瞬間」就會被執行,但其實工程師在開發時只要遵守以下幾個原則,就不用太擔心 XSS 攻擊!
- 不隨意使用
innerHTML - 對輸入做驗證
- 對輸出做過濾
簡單來說,XSS 的核心問題其實只有一個: 網站信任了不該信任的輸入。
只要使用者輸入的內容沒有經過適當的驗證與過濾,就可能被當成程式碼執行。
參考資料:
如果有理解錯誤的地方歡迎指正👏🏻