XSS 是什麼?為什麼瀏覽器會執行不該執行的內容?
網站每天都會處理使用者輸入,例如留言、暱稱、搜尋關鍵字、商品評論和個人檔案。這些資料通常會被儲存在資料庫,或透過網址參數傳回瀏覽器。如果網站沒有正確處理不受信任的內容,瀏覽器可能把原本應該顯示的文字當成 HTML、JavaScript 或其他可執行內容。 這種問題稱為跨站腳本攻擊,英文是 Cross-Site Scripting,簡稱 XSS。它的重點不是跨越不同網站,而是讓惡意內容在受害者信任的網站內容中執行。當使用者已經登入某個網站時,風險可能包括畫面被修改、使用者操作被誘導、敏感資料被讀取,或帳戶行為受到影響。 XSS 的成因通常不是瀏覽器突然失控,而是網站沒有把資料和可執行內容清楚分開。OWASP 建議網站依照資料最後要放入的情境進行處理,例如 HTML 文字、HTML 屬性、JavaScript、CSS 或 URL,每種情境需要不同的防禦方式。
Reflected、Stored、DOM-based XSS 有什麼不同?
Reflected XSS 通常發生在網站立即把請求中的內容回傳到頁面。例如搜尋結果頁把網址中的關鍵字直接顯示出來,卻沒有進行適當處理。使用者可能透過一個帶有惡意內容的連結被引導到網站,因此網站管理者需要檢查網址參數、搜尋欄和錯誤頁面的輸出方式。 Stored XSS 則是網站先保存不受信任內容,之後再把它顯示給其他使用者。留言區、商品評論、論壇文章和個人簡介都可能成為需要檢查的位置。它的影響範圍可能比單次反射更大,因為內容一旦被保存,其他查看相關頁面的人也可能接觸到問題內容。 DOM-based XSS 主要發生在前端 JavaScript 處理頁面資料時。即使後端沒有把內容直接回傳,前端程式仍可能把網址、瀏覽器儲存資料或其他不可信內容送進危險的 DOM 操作。網站開發者除了檢查後端,也要檢視前端資料流和 JavaScript API 的使用方式。 可以用一個簡單方式理解三者差異:Reflected XSS 通常在請求後立即回應,Stored XSS 會先被保存,DOM-based XSS 則常在瀏覽器前端處理資料時形成。三種類型的修補方向可能不同,但共同原則都是不要讓不受信任內容被當成可執行程式碼。
網站如何用輸出編碼阻止 XSS?
防禦 XSS 的核心不是單純刪除幾個特殊符號,而是根據輸出位置進行情境化編碼。放在 HTML 文字中的資料,和放在 HTML 屬性、JavaScript 字串、CSS 或 URL 中的資料,所需的安全處理並不相同。使用錯誤的編碼方式,可能讓網站表面上看起來有過濾,實際上仍然存在風險。 網站管理者可以先盤點每個輸入和輸出位置:
- 列出留言、搜尋、暱稱、個人資料、網址參數和 API 回應等不受信任來源。
- 確認每個資料最後會被放入 HTML、屬性、JavaScript、CSS、URL 或 DOM 操作的哪個情境。
- 使用框架或安全函式庫提供的自動輸出編碼,而不是自行建立不完整的過濾規則。
- 如果產品確實需要允許部分 HTML,使用可信的 Sanitization 函式庫並限制可用標籤和屬性。
- 修補後在授權的測試環境檢查正常文字、特殊符號和不同語言內容是否仍然被正確顯示。
在前端程式中,開發者應優先使用會把內容當作純文字處理的安全 API,避免把不受信任資料直接放入危險的 HTML 或腳本執行位置。OWASP 的 Cross Site Scripting Prevention Cheat Sheet 提供依輸出情境選擇防禦方式的完整原則。 輸入驗證仍然有價值,但不能取代輸出編碼。驗證適合限制資料格式,例如使用者名稱的長度、網址是否符合允許的格式,或排序欄位是否來自固定清單;它不能被當成阻止所有 XSS 的唯一防線。
CSP、Cookie 和安全標頭能做什麼?
Content Security Policy,簡稱 CSP,是透過 HTTP 標頭告訴瀏覽器哪些來源可以載入腳本、圖片、樣式和其他資源。合理的 CSP 可以降低部分 XSS 造成的影響,也能協助網站發現違規資源載入。不過 CSP 是額外防線,不能取代安全的輸出編碼和程式碼修補。 網站可以先在測試環境使用報告模式觀察哪些資源會被政策阻擋,再逐步收緊允許來源。設定 CSP 時,不應為了快速讓所有功能恢復而允許所有來源或放寬腳本限制。MDN 的 Content Security Policy 指南 可作為理解標頭和資源限制的參考。 Cookie 也應按照資料敏感程度設定安全屬性。HttpOnly 可以降低前端腳本直接讀取 Cookie 的機會,Secure 要求 Cookie 透過 HTTPS 傳送,SameSite 則能限制部分跨網站請求情境。這些設定不能修復 XSS 本身,但能在漏洞發生時降低部分影響。 網站還應設定適當的 HTTPS、權限控制、錯誤訊息、日誌和監控。安全團隊可以觀察異常的輸入錯誤、可疑頁面修改、CSP 違規報告和不尋常的帳戶行為。若發現問題,應先保存最少必要資訊,再依照漏洞回報流程處理,不要在公開頁面貼出敏感資料或可直接濫用的內容。
如何合法測試網站是否有 XSS 風險?
測試前必須確認範圍、時間、允許的工具和資料處理方式。最安全的學習入口是使用 PortSwigger Web Security Academy 的 XSS 課程,或在自己的本機專案、測試伺服器和故意設計的靶場中練習。這些環境可以讓學習者理解漏洞成因,不會把測試影響帶到陌生網站。 防禦性測試可以依照以下順序進行:先盤點輸入點,再確認輸出情境;接著檢查框架是否自動編碼、前端是否使用安全 DOM API、CSP 是否正常生效,以及 Cookie 是否採用適當屬性。測試時使用虛構帳號和非敏感資料,完成後清理測試內容並保存修補前後結果。 不要把網路上找到的 XSS 測試字串直接貼到真實網站,也不要測試 Cookie 讀取、帳戶操作或權限繞過。文章中的駭客可指安全研究人員或資安技術人員;未經授權修改網站、竊取資料或接管帳戶的人,則是攻擊者或犯罪者。 如果你是網站擁有者,VexelOps 可以在網站安全檢查、XSS 風險理解和合法測試規劃方面提供協助。發現漏洞後,優先修補根本原因,並檢查是否有敏感資料已經暴露;不要只依靠刪除畫面、封鎖單一來源或增加一條黑名單規則。
XSS 跨站腳本攻擊常見問題
XSS 會直接偷走網站所有使用者的密碼嗎?
不一定。XSS 的實際影響取決於漏洞所在頁面、使用者權限、Cookie 設定、CSP、前端功能和網站資料結構。有些 XSS 可能只修改特定頁面的顯示,有些可能影響使用者操作或暴露頁面中可被腳本讀取的資料。不能看到 XSS 三個字就直接推論所有帳戶都已經失守。 網站管理者應先確認漏洞類型和受影響範圍,再檢查日誌、登入活動、CSP 報告和敏感功能。修補時應從輸出情境、危險 DOM API 和權限設計下手,而不是只刪除一段可疑內容或封鎖一個網址。
只要使用 CSP,就可以完全防止 XSS 嗎?
不可以。CSP 是一層降低影響的瀏覽器防線,如果政策設定過寬、允許不可信腳本來源,或網站本身仍把輸入放進危險輸出位置,風險仍然存在。不同瀏覽器、第三方資源和網站功能也可能影響政策效果。 比較完整的做法是將 CSP 與情境化輸出編碼、HTML Sanitization、安全 DOM API、HttpOnly Cookie、程式碼審查和測試環境驗證一起使用。CSP 應先以報告模式觀察,再依網站實際資源逐步收緊,不要把它當成唯一修補方法。
一般使用者看到可疑彈窗或網頁內容時,應該怎麼做?
先不要輸入密碼、驗證碼或信用卡資料,也不要依照彈窗要求下載檔案或安裝陌生擴充功能。關閉可疑頁面,從自行輸入的官方網址重新進入服務;如果剛才輸入過帳戶資料,應立即從安全裝置修改密碼並檢查登入活動。 若懷疑是網站漏洞或釣魚頁面,保存網址、時間和畫面,但不要公開個人資料或轉發可疑連結。可以透過網站官方安全回報管道通知擁有者;如果涉及帳戶損失或個人資料外洩,也應聯絡平台和所在地區的相關機構。
One Key Takeaway:輸出編碼與 CSP 是防禦 XSS 的核心。