產業資訊

資安知識18 分鐘閱讀

XSS 是什麼?Stored、Reflected、DOM-based 的檢測與修復完整指南

XSS 的根因是外部資料進入瀏覽器可執行的情境。完整解析 Stored、Reflected 與 DOM-based XSS、情境式輸出編碼、HTML Sanitization、安全 DOM API、CSP、Trusted Types 與修復複驗。

Cross-Site Scripting(XSS)不是單純讓頁面多出一段 HTML,而是應用程式讓不受信任資料跨越內容與程式碼的邊界,使瀏覽器在網站來源的安全脈絡中執行攻擊者控制的內容。有效防護必須知道資料最後進入 HTML、Attribute、URL、JavaScript、CSS 或 DOM 的哪一種情境,再選擇正確的輸出編碼、安全 API 或 HTML Sanitization。

網站輸入跨越內容區進入瀏覽器執行區,並在多位訪客開啟同一網站頁面時觸發安全警示
01

先講結論:讓資料只被顯示,不被瀏覽器當成程式執行

CWE-79 將 XSS 描述為:不受信任資料進入 Web 應用程式,應用程式在產生頁面時沒有防止其中的內容被瀏覽器執行,受害者開啟頁面後,內容便在該網站的來源脈絡中運作。根因不是某一個特殊字元,而是資料被放進可以改變文件結構或執行程式碼的位置。

安全設計要同時回答兩個問題。第一,產品是否只需要顯示純文字?如果是,應使用框架預設自動跳脫、情境式輸出編碼與 textContent 等安全輸出方式。第二,產品是否真的需要讓使用者提交富文字 HTML?如果需要,則應使用成熟且持續更新的 HTML Sanitizer,限制允許的標籤、屬性與 URL Scheme。

OWASP 強調沒有單一技術能處理所有 XSS 情境。最佳基線是框架安全預設、靠近輸出位置的情境式編碼、安全 DOM Sink 與必要時的 HTML Sanitization;CSP、Trusted Types、Cookie 屬性與 WAF 則放在縱深防禦層。

  • 先辨識資料的來源、生命週期與最後輸出情境
  • 純文字使用情境式輸出編碼與安全 DOM API
  • 需要富文字時使用成熟 HTML Sanitizer,不自行以正規表示式清理 HTML
  • 禁止外部資料進入 Script、事件處理器、Tag/Attribute 名稱等危險情境
  • 用 CSP、Trusted Types、HttpOnly 與監控限制失守後的影響
  • 修復後以原始條件、同根因範圍與正常輸入共同複驗
02

為什麼 XSS 特別危險?程式碼會在受信任網站的 Origin 中執行

瀏覽器以 Origin 區分網站安全邊界。當注入內容在受害網站頁面中執行,它通常能以該頁面既有權限讀取 DOM、觀察畫面內容、呼叫同源 API、操作表單、修改介面或代表目前使用者執行網站允許的動作。這也是為什麼 XSS 不是單純的畫面破版。

HttpOnly Cookie 會阻止 JavaScript 直接讀取該 Cookie,但不會阻止惡意程式利用瀏覽器自動攜帶 Session 呼叫同源功能,也不會保護頁面中的 CSRF Token、Local Storage、非 HttpOnly Cookie 或敏感 DOM 內容。影響要依受害者角色、可見資料、可執行功能與安全控制實際評估。

管理後台、客服介面、內容審核、工單系統與多人協作產品通常風險較高,因為低權限使用者提交的內容可能由高權限人員開啟。只在輸入者自己的瀏覽器出現的問題,則要進一步確認是否能影響他人;不能把所有在 Console 中貼入程式碼的 Self-XSS 都當成產品弱點。

  • 讀取頁面上目前使用者可見的個資、交易、Token 或商業資料
  • 代表使用者呼叫同源 API、修改設定或提交操作
  • 竄改介面、插入假表單或引導使用者完成錯誤動作
  • 影響檢視已儲存內容的其他使用者、客服或管理者
  • 把既有帳號權限與應用程式功能轉化為更大的業務影響
03

Stored、Reflected、DOM-based 有什麼差別?

三類 XSS 的核心風險相同,但資料路徑不同。Reflected XSS 通常把請求中的輸入直接帶回同一次 HTTP 回應;Stored XSS 先把輸入存入資料庫、CMS、日誌或其他儲存,再由另一個頁面或使用者讀取;DOM-based XSS 則主要發生在瀏覽器端,前端程式把 URL、Storage、postMessage 等來源送進會解析 HTML 或執行程式碼的 Sink。

分類不是互斥的漏洞嚴重度。Stored XSS 常能在受害者未點擊特製連結的情況下觸發,且可能影響高權限檢視者;Reflected XSS 仍可能透過可信網站連結、轉址或社交工程造成影響;DOM-based XSS 可能完全不把有害值送到伺服器,因此傳統只看 HTTP 回應的掃描器容易漏掉。

實務報告應同時記錄『資料是否儲存』與『執行發生在伺服器產生的 HTML,還是瀏覽器端 DOM 資料流』,不要只用一個標籤取代完整路徑。

Stored、Reflected 與 DOM-based XSS 的資料路徑、觸發與檢測重點
類型資料路徑常見觸發檢測重點
Reflected XSSRequest 輸入進入同一次 Server Response受害者開啟帶有特定輸入的連結或提交請求比對請求與回應,確認輸出情境及實際瀏覽器解析
Stored XSS輸入先儲存,再由其他頁面、角色或時間讀取使用者開啟留言、個人資料、工單、報表或後台內容追蹤寫入與所有讀取點,使用不同角色驗證
DOM-based XSS瀏覽器端 Source 經 JavaScript 流向危險 Sink頁面載入、Hash/URL 變更、postMessage 或前端互動分析 Client-side Data Flow、DOM Sink 與實際瀏覽器行為
Blind XSS儲存輸入在不可見的內部介面或第三方系統觸發客服、稽核、日誌、監控或管理人員檢視資料需在授權測試環境建立安全回呼與跨角色觀測
Self-XSS使用者自行在 Console 或欄位執行內容通常需要受害者主動貼上程式碼或繞過警告確認是否存在可影響他人的產品資料流,避免誤報
04

XSS 從哪裡進來?不要只測搜尋框與留言欄

不受信任資料可能來自 URL Query、Path、Fragment、表單、JSON、Cookie、Referer、檔案名稱、Webhook、第三方 API、CMS、資料庫紀錄或即時訊息。資料即使已存進內部系統,也不會因此變成可信;當它在另一個輸出點進入不同情境,仍需要相對應的防護。

DOM-based XSS 特別需要盤點 Source 與 Sink。常見 Source 包括 location、document.referrer、Storage、postMessage 與 API 回應;危險 Sink 則包括 innerHTML、outerHTML、insertAdjacentHTML、document.write、eval 類介面、字串形式的計時器與動態 Script URL。真正要查的是資料是否能從 Source 到達 Sink,以及沿途是否有正確、不可繞過的轉換。

一個值可能在同一產品中被輸出多次:先出現在 HTML 文字,之後進入 Attribute,再被 JavaScript 讀取並寫回 DOM。第一次做過 HTML Encoding,不代表後續 JavaScript 或 URL 情境仍然安全;每一次跨入新解析器都要重新檢查。

XSS 常見資料來源、輸出位置與容易忽略的路徑
資料來源可能輸出位置容易忽略的路徑
URL 與導覽狀態搜尋結果、錯誤頁、Breadcrumb、前端 RouterFragment 不會送到伺服器,但可能被前端寫入 DOM
使用者內容留言、名稱、簡介、工單、富文字、檔名後台、通知信、匯出報表與審核預覽使用不同模板
HTTP 與瀏覽器狀態Cookie、Referer、User-Agent、Local/Session Storage分析、客服或偵錯頁會顯示原本不在 UI 的值
跨視窗訊息postMessage、Iframe、Web Worker未驗證 Origin,或把 message.data 直接送入 HTML Sink
第三方與內部資料API、Webhook、CMS、資料庫、日誌來源被稱為內部,但內容最初仍可能由外部控制
前端元件狀態Template、Tooltip、Modal、Markdown、圖表標籤安全字串在外掛或元件內被重新解碼、拼接或解析
05

怎麼安全檢測 XSS?先以非執行標記定位資料流

XSS 測試必須建立在合法授權、明確資產範圍與停止條件上。第一階段不需要執行程式碼,可先為每個輸入使用唯一且不具執行能力的標記,追蹤它是否出現在回應、DOM、Attribute、Script、URL、CSS、管理後台或其他角色的頁面,並記錄瀏覽器最後如何解析。

只有在隔離或核准環境、且需要證明實際可執行性時,才使用無害的本地效果作為最小證據,例如改變專用測試元素或設定測試旗標;不要擷取 Cookie、讀取真實資料、對外送出內容、呼叫敏感 API 或影響其他使用者。Stored/Blind XSS 測試要使用專用帳號、資料與回呼端點,並在完成後清除測試內容。

對 DOM-based XSS,單看伺服器回應找不到完整證據。需要在真實瀏覽器中觀察 Source 到 Sink 的資料流、DOM 變化與 JavaScript 執行點,並結合 SAST、IAST、Browser Instrumentation 或程式碼審查。測試時一次只改一個變因,避免把框架錯誤、外掛行為或瀏覽器擴充功能誤判為網站弱點。

06

一筆可信的 XSS 發現需要哪些證據?

報告不能只附一張彈出視窗截圖。至少要記錄資產、路徑、HTTP 方法、輸入欄位、角色、租戶、環境、瀏覽器與版本,並說明資料從哪個 Source 經過哪些轉換,最後進入哪個輸出情境或 DOM Sink。對 Stored XSS,還要分開記錄寫入者與觸發者。

證據應保存正常基線、非執行標記的原始輸入、Server Response、最終 DOM、相關 Network/Console/CSP Report,以及最小無害驗證結果。若使用瀏覽器開發工具取得證據,要註明觀察的是原始 Response 還是 JavaScript 執行後的 DOM,兩者可能完全不同。

影響評估要以受害者權限與可達功能為基礎。可以證實頁面執行非預期內容,不代表已證實所有帳號都可被接管;反過來,即使 HttpOnly 阻止讀取 Cookie,惡意內容仍可能代表使用者操作同源功能。報告應分開列出已證實行為、合理可達影響與未驗證假設。

XSS 最小可複驗證據包
證據應記錄內容保護與判讀要求
資產與角色Host、Path、方法、參數、角色、租戶、環境、版本Stored XSS 分開記錄寫入與檢視角色
資料流Source、Server/Client 轉換、Template/Component、最終 Sink區分原始 Response 與執行後 DOM
輸出情境HTML Text、Attribute、URL、JavaScript、CSS 或 DOM API說明目前防護為何不符合該情境
最小驗證不具外洩或破壞能力的可重複瀏覽器效果不讀取真實資料、不呼叫敏感 API、不影響第三人
影響與控制受害者權限、可見資料、同源功能、CSP、Cookie 與 Sanitizer區分根因防護與縱深控制
複驗資料修復版本、部署範圍、原始條件、同根因位置與正常回歸提供安全重測條件,不公開可濫用細節
07

核心修復一:依輸出情境使用正確的 Encoding

Output Encoding 的目的,是把不受信任資料轉成瀏覽器只會顯示、而不會解讀為文件結構或程式碼的形式。關鍵是 Encoding 必須依最後輸出情境選擇;HTML Text、HTML Attribute、URL、JavaScript 與 CSS 由不同解析器處理,錯用情境可能留下弱點或造成雙重編碼。

最好的起點是使用現代框架的預設模板輸出,讓框架以文字方式處理變數,並避免繞過機制。若需要自行輸出,則使用成熟且能明確指定 Context 的 Encoder,並盡量靠近真正 Render 的位置執行,而不是在 Request 入口統一把所有輸入先做一次 HTML Encoding。

有些位置本質上過於危險,例如未受控的 Script 內容、事件處理器、Tag 名稱、Attribute 名稱、HTML Comment、CSS Selector 或可執行 URL。這些地方不是換一種 Encoding 就能普遍安全,設計上應禁止外部資料進入。

XSS 輸出情境、主要防護與危險用法
輸出情境主要防護設計注意事項
HTML Text框架自動跳脫或 HTML Entity Encoding純文字優先使用 textContent,不以 innerHTML 顯示
安全 HTML Attribute 值Attribute Encoding 並以引號包住完整值Attribute 名稱固定,禁止 onEvent 等可執行屬性
URL 參數先對參數做 URL Encoding,再依外層 Attribute 編碼驗證 Scheme,只允許產品所需的安全協定
JavaScript 資料值優先移出 Inline Script;必要時限定在引號資料值並做 JS Encoding不可把外部資料放進程式結構、事件處理器或 eval 類介面
CSS Property 值限制合法值並使用 CSS Encoding禁止外部資料控制 Selector、Property 名稱或可載入資源的危險值
富文字 HTML成熟 HTML Sanitizer 與嚴格允許清單Sanitize 後不可再拼接、解碼或交給會改寫 HTML 的不可信元件
08

安全資料流:輸入經情境式編碼後,只能進入內容區

下圖將核心原則視覺化:不受信任輸入先經過對應輸出情境的轉換,成為只供顯示的文字資料,再放進瀏覽器的內容區;執行區保持封閉,輸入無法改變頁面程式結構。這個控制應位於最接近輸出的 Template、Component 或 DOM 更新點。

相反地,若資料在入口已做 HTML Encoding,後來卻被解碼、拼進 JavaScript,或交給 innerHTML 重新解析,原本的保護就可能失效。資料跨越每一個 Parser 與信任邊界時,都要重新確認目前 Context 與安全 Sink。

網站輸入經情境式輸出編碼轉成不可執行的文字片段,只放入瀏覽器內容區並與執行區保持分離
XSS 防護的核心是讓資料保持為資料;Encoding 必須在正確的輸出情境、靠近 Render 的位置執行。
09

核心修復二:需要富文字時使用 HTML Sanitization

文章編輯器、留言格式、商品說明或 Markdown 預覽有時需要保留連結、段落、清單與部分樣式。若將所有 HTML 全部 Encoding,功能就會失去格式;這時應使用經廣泛檢驗的 HTML Sanitizer,移除或改寫可執行標籤、危險屬性、URL Scheme 與瀏覽器解析邊界。

不要用正規表示式、字串取代或自製黑名單解析 HTML。瀏覽器容錯解析、SVG/MathML、編碼、Namespace、DOM Clobbering 與 Mutation XSS 會讓簡單規則難以完整處理。OWASP 建議使用成熟 Sanitizer,例如 DOMPurify,並持續更新,因為瀏覽器行為與繞過方式會改變。

Sanitize 後的內容也不能被再次破壞。若後續程式拼接未清理片段、重新解碼、改寫 Attribute,或第三方元件以不同方式解析 Sanitized HTML,原本的保護可能失效。系統應記錄 Sanitizer 版本與設定,建立固定惡意樣本回歸測試,並在更新瀏覽器或編輯器後重新驗證。

  • 依產品需求建立最小 Allowlist,只保留必要標籤、屬性與安全 URL Scheme
  • Sanitization 在可信邊界集中執行,前後端責任與版本清楚
  • Sanitize 後不再與未清理字串拼接,也不交給會重新解碼的元件
  • 定期更新 Sanitizer 與瀏覽器相容設定,追蹤安全公告
  • 對既有儲存內容安排重新清理或 Render-time Sanitization 策略
10

DOM-based XSS:優先改用安全 Sink,不要只在 Source 過濾

DOM-based XSS 的根因通常是前端把可控字串送進會解析 HTML 或執行程式的 API。較可靠的修復是改變 Sink:顯示純文字使用 textContent;建立節點使用 createElement 與 appendChild;設定固定且無執行能力的 Attribute 時使用 setAttribute;處理 URL 時使用 URL API 並驗證 Scheme。

innerHTML、outerHTML、insertAdjacentHTML 與 document.write 會解析 HTML;eval、Function Constructor 與字串形式的計時器會把資料當程式;Script、Iframe 與部分 URL 屬性也可能形成執行路徑。若功能不需要解析,就不應使用這些介面。

不能只在 location.hash 或 message.data 進入時做一次通用過濾,因為同一資料可能流向多種 Sink。應用 Source-to-Sink 分析找出所有資料流,在 Sink 前使用符合 Context 的控制;接收 postMessage 時還要驗證 Origin、資料結構與允許動作。

常見 DOM Sink 的安全替代與使用條件
需求優先使用避免或嚴格限制
顯示純文字textContentinnerHTML、document.write
建立 DOM 結構createElement、appendChild、固定 Component Template以字串組合完整 HTML
設定一般屬性固定 Attribute 名稱的 setAttribute 或型別化 Property事件屬性、任意 Attribute 名稱
建立 URLURL/URLSearchParams、Scheme Allowlistjavascript:、未驗證 data:、字串拼接 Script URL
解析富文字受控 Sanitizer 產生的 Trusted HTML把原始使用者 HTML 直接送入解析 Sink
執行程式邏輯函式與結構化資料eval、Function、字串形式 setTimeout/setInterval
11

React、Vue、Angular 等框架為什麼仍會出現 XSS?

現代框架通常會對模板中的文字變數自動跳脫,降低最常見的 Server/Client Rendering XSS。但框架不會自動保護所有情境:開發者繞過輸出保護、注入 Raw HTML、信任未驗證 URL、直接操作 DOM、使用不安全第三方元件或建立 Template Injection,都可能重新打開執行路徑。

React 的 dangerouslySetInnerHTML、Vue 的 v-html、Angular 的 bypassSecurityTrust 系列、Lit 的 unsafeHTML,以及任何直接操作 innerHTML 的封裝,都應視為高風險 Escape Hatch。使用前要證明資料來源、Sanitizer、允許清單與輸出位置安全,並限制成少數可審查的共用元件。

Server-side Rendering、Hydration 與前端狀態序列化也要納入。把未信任資料直接嵌入 Inline Script、JSON 若以錯誤 Content-Type 回傳、或把伺服器傳來的字串再次解析成 HTML,都可能讓框架預設保護失效。

  • 建立 Raw HTML/Trusted HTML 的集中元件與審查規則,不允許任意散落
  • 禁止將使用者輸入直接放入 Inline Script、Event Handler 或動態 Template
  • 對 href、src、style 與第三方元件另外執行 URL/CSS/元件安全檢查
  • 用 SAST/Lint 尋找危險 API 與框架 Escape Hatch,並建立 Code Owner
  • 更新框架、Sanitizer、Markdown Renderer 與富文字編輯器的安全版本
12

CSP 與 Trusted Types:把瀏覽器變成第二道閘門

Content Security Policy 可以限制哪些 Script 能執行、資源可從哪裡載入,並透過 Report-Only 或 Reporting 收集違規訊號。較強的策略通常以每次回應的 Nonce 或可信 Script Hash 為核心,搭配 strict-dynamic、object-src 'none' 與 base-uri 'none';單純列出大量 Host,或保留 unsafe-inline,常會削弱防護。

CSP 是縱深防禦,不是 XSS 根因修復。錯誤設定、允許來源上的可控 Script、JSONP、第三方供應鏈與既有 Gadget 都可能形成繞過;部分 DOM 操作也可能不需要載入新的外部 Script。應先修正 Encoding、Sanitization 與 Sink,再逐步導入 CSP。

Trusted Types 可在支援的瀏覽器中要求 innerHTML、document.write、Script URL 等 Injection Sink 不接受普通字串,只能接受經核准 Policy 產生的 TrustedHTML/TrustedScriptURL 等型別。它能把散落的 DOM 寫入集中到可審查 Policy,但 Policy 若直接放行輸入仍不安全;導入時應先盤點違規、以 Report-Only 找出舊程式,再讓 Policy 委派給可靠 Sanitizer。

XSS 根因控制與縱深防禦的角色分工
控制主要作用不能取代什麼
情境式 Output Encoding讓純文字在指定 Context 中只被顯示不能安全保留任意富文字,也不能跨 Context 重用
HTML Sanitization保留允許的富文字並移除可執行結構不能保護後續再次拼接、解碼或其他非 HTML Context
安全 DOM Sink避免把字串當 HTML 或程式解析不能修正其他仍使用危險 Sink 的路徑
CSP限制 Script 執行與資源來源,提供違規報告不能取代 Encoding、Sanitization 與安全 Sink
Trusted Types在支援瀏覽器限制高風險 DOM Sink 的字串輸入不能保證自訂 Policy 本身正確,也不是跨瀏覽器唯一防線
HttpOnly/SameSite Cookie限制部分 Token 存取或跨站請求情境不能阻止頁面內程式執行與同源操作
WAF偵測或暫時阻擋部分已知 Payload不能可靠防止 DOM XSS、編碼繞過與應用程式根因
13

為什麼全域 Filter、WAF 與封鎖關鍵字不是完整修復?

全域 Request Filter 不知道資料最後會進入 HTML、Attribute、URL、JavaScript 還是 CSS,因此無法選擇正確 Encoding。若先做 HTML Encoding,之後資料進入 JavaScript Context,防護可能不適用;如果開發端又在輸出時編碼,還可能造成 O'Hara、Unicode 或富文字內容被雙重轉換。

以黑名單封鎖 Script、事件名稱、引號或特定字串,無法涵蓋瀏覽器容錯解析、不同編碼、Namespace、URL Scheme、DOM API 與未來語法;同時容易擋住合法內容。WAF 更看不到只在瀏覽器內由 location.hash、Storage 或 postMessage 形成的 DOM XSS。

這些控制可用於緊急降低暴露、發現攻擊跡象或阻擋已知模式,但工單仍應保留永久修復:找到實際輸出 Context、改用安全 Sink、加入正確 Encoder 或 Sanitizer,並在修復後依原始資料流複驗。

14

如何把 DAST、SAST、IAST 與人工測試組合起來?

DAST 能從執行中的網站探索輸入、反射與瀏覽器行為,適合找公開端點與實際 Render 問題;若支援真實瀏覽器與 JavaScript Instrumentation,對 DOM-based XSS 的覆蓋會更好。但登入、角色、富文字工作流、後台觸發與 Blind XSS 仍取決於 Crawl、測試資料與跨角色流程。

SAST 可搜尋框架 Escape Hatch、危險 DOM Sink 與 Source-to-Sink Data Flow,較容易找尚未由測試流量觸發的程式路徑;IAST 在測試執行期間觀察資料流與 Sink,能降低定位成本,但仍受功能測試覆蓋限制。人工測試則適合驗證複雜 Context、Parser 差異、Stored/Blind 流程與實際影響。

最完整的做法是在開發階段以安全元件、Lint、SAST 與 Code Review 防止新問題,在測試環境用 IAST/DAST 與跨角色測試驗證,正式環境則用 CSP Report、前端 Error、WAF 與異常行為監控補充可見度。任何單一工具的『未發現』都不能證明不存在 XSS。

15

修復後如何複驗?不只確認彈出效果消失

XSS 複驗要以原始 Source、角色、輸出位置、瀏覽器與觸發流程重測,確認原始輸入在 Server Response 與最終 DOM 中都只被當成資料。若修復只是 WAF 阻擋、CSP 阻止 Script 執行或頁面不再顯示錯誤,底層不安全 Sink 可能仍然存在。

接著檢查同根因範圍:相同欄位是否也出現在搜尋、列表、詳細頁、後台、通知、預覽、匯出與行動版?共用 Markdown Renderer、Tooltip、Modal、表格或 Raw HTML 元件是否仍會解析?DOM Source 是否能從其他 URL、Storage 或 postMessage 路徑到達同一 Sink?

最後要做正常回歸。合法的特殊字元、多語系、連結、Markdown 與允許的富文字應繼續正確顯示;Sanitizer 不應破壞必要格式;CSP/Trusted Types 不應造成大量 Runtime Error。安全修復必須同時證明不可執行與功能仍可用。

XSS 修復後的複驗條件
複驗面向通過條件不充分的結案證據
原始資料流相同 Source 與觸發流程只產生不可執行內容彈出視窗不再出現
輸出情境每個 Render 點使用正確 Context Encoding 或安全 Sanitizer入口增加通用字元過濾
DOM Sink危險 Sink 已移除、封裝或只接受可信型別CSP 目前阻止了執行
Stored/跨角色所有儲存內容讀取點、角色與後台頁均重測只測寫入者自己的前台頁
同根因範圍共用元件、API、行動版、預覽、通知與匯出已納入只修報告中的單一 URL
縱深控制Strict CSP/Trusted Types/Cookie/監控按設計運作以 WAF 規則取代程式修復
正常回歸合法特殊字元、多語系與允許富文字正確顯示只用攻擊型輸入測試
16

如果 XSS 可能已被利用,應轉入事件應變

若 CSP Report、前端 Telemetry、WAF、CDN 或應用程式日誌顯示可疑 Script、異常外連、未知 DOM 修改、敏感 API 操作或高權限使用者開啟可疑內容,處理範圍已超過一般弱點修復。團隊應保存頁面版本、儲存內容、HTTP/瀏覽器/CSP/身分與 API 日誌,建立時間線並限制持續觸發。

Stored XSS 要找出所有儲存位置、受影響 Render 點與可能開啟內容的使用者;必要時下架內容、停用功能、撤銷 Session、輪替 Token/API Key,並檢查帳號設定、交易、權限與資料是否被非預期操作。若 Script 可能接觸敏感資訊,還要依資料分類、契約與法規評估通知義務。

清除單一惡意內容不代表事件結束。還要修正共用根因、搜尋其他同類內容、確認第三方 Script 與依賴沒有被竄改、檢查持久化變更,並以新的安全測試與監控規則驗證攻擊路徑已關閉。

17

開發與維運團隊的 XSS 防護清單

將 XSS 防護變成設計與交付標準,比在上線後追逐 Payload 更有效。以下清單可加入 Architecture Review、Pull Request、Definition of Done、發布與修復複驗。

  • 所有外部與儲存資料都標記信任來源,盤點每一個輸出 Context 與 DOM Sink
  • 純文字使用框架預設跳脫、Context Encoder 與 textContent 等安全 API
  • 需要富文字時使用集中、最小 Allowlist、持續更新的 HTML Sanitizer
  • 禁止 Raw HTML、innerHTML、document.write、eval 類 API 與 Framework Escape Hatch 任意散落
  • URL 驗證 Scheme;postMessage 驗證 Origin 與資料結構;避免不受控 Script/Event Context
  • 導入 Strict CSP Report-Only、CSP Reporting 與支援環境的 Trusted Types,再逐步強制
  • HttpOnly、Secure、SameSite、最小 Token 暴露與前端敏感資料最小化同步落實
  • 結合 SAST、DAST、IAST、人工跨角色測試與瀏覽器監控,不以單一工具代替完整覆蓋
  • 修復後重測原始資料流、所有同根因輸出點、正常多語系與富文字功能
18

真正的 XSS 防護,是管理每一次資料進入瀏覽器解析器的邊界

Stored、Reflected 與 DOM-based XSS 看似走不同路徑,最終都回到同一件事:瀏覽器把原本應是資料的內容當成可執行結構。修復者必須知道資料最後進入哪一個 Parser 與 Sink,為純文字使用正確 Context Encoding,為必要富文字使用可靠 Sanitization,並避免危險輸出位置。

當框架安全預設、安全 DOM API、CSP、Trusted Types、Cookie 屬性、監控與修復複驗形成閉環,團隊才能同時降低弱點發生率、限制失守後影響,並用可驗證證據證明問題真正關閉。

REF

資料來源

Redmark Editorial
START WITH ONE WEBSITE

從第一個網站開始,建立持續弱掃流程

以更低的執行成本持續檢測網站弱點,更早發現問題,也讓每一次修復都有清楚的方向。

免費開始掃描