July 25, 2026
【網路資安筆記】「只是按了個連結,錢就被轉走了?」一文搞懂前端兩大經典威脅 XSS 與 CSRF
大家是否常常為了方便,讓瀏覽器自動「記住」各大平台的登入密碼呢?在追求便利的同時,是否曾經懷疑過這樣背後到底隱藏著什麼樣的安全風險?

By Chwang
8 min read
這週剛好有朋友問我什麼是 XSS 和 CSRF,這兩個堪稱網頁前端資安界的「經典款」攻擊。隨著 AI 時代來臨,各式各樣的網路應用如雨後春筍般出現,但大家在開心使用的同時,是否有考量過網路安全這件事呢?根據權威機構的調查顯示,全球高達 40% 到 60% 以上 的網站都存在著安全漏洞,這是一個非常驚人的數字!
現代前端已不再只是靜態內容的檢視器,而是具備複雜邏輯的「厚客戶端執行環境」(Thick-client execution environment)。從戰略角度看,前端已成為應用程式最主要且脆弱的攻擊平面。今天這篇就讓我們一起來深入淺出地瞭解這兩者究竟是什麼,以及在開發與使用過程中我們該如何防禦吧!
從架構師的高度來看:
XSS 與 CSRF 的本質差異,在於「執行邊界」與「身份邊界」的崩潰
- XSS 是「入站(Inbound)」的內容污染: 騙用戶執行惡意代碼,目標是獲取控制權與竊取資料
- CSRF 是「出站(Outbound)」的身份冒用: 騙瀏覽器發送惡意請求,目標是利用登入狀態執行未授權操作
一、 XSS:躲在信任網頁背後的數位扒手
跨網站指令碼 (Cross-Site Scripting, XSS) 是一種典型的「代碼注入」漏洞。當網站未能區分「受信任的應用邏輯」與「不可信的用戶數據」時,攻擊者就能繞過同源政策(SOP),將惡意 JavaScript 注入受害者的瀏覽器環境中。
由於該代碼運行在受信任的 DOM(文件物件模型)中,瀏覽器會將其視為合法邏輯執行,駭客就能像個「數位扒手」一樣,在我們不自覺的情況下偷走敏感資訊
XSS 的三種常見攻擊劇本
- 儲存型 (Stored XSS):
- 機制: 最具威脅的持久型漏洞。惡意腳本被永久存入伺服器資料庫(如留言板、使用者設定檔)。每一位瀏覽該頁面的使用者都會自動下載並執行,具備大規模破壞力。
- 案例: 2015 年喜馬拉雅平台漏洞,攻擊者將「專輯名稱」設為 JavaScript。每位開啟該專輯的用戶,瀏覽器都會從資料庫抓取並自動執行該段惡意腳本
2. 反射型 (Reflected XSS):
- 機制: 惡意代碼通常夾帶在 URL 參數中。當用戶點擊釣魚連結,伺服器未經過濾便將數據「反射」回回應頁面並執行。此路徑必經伺服器,但數據不具持久性
- 範例: 點擊
[https://bank.com/search?q=](https://bank.com/search?q=)<script>alert('XSS')</script>即中招
3. DOM 型 (DOM-based XSS):
- 機制: 完全發生在客戶端的漏洞。數據流向(Source)到觸發點(Sink)均在瀏覽器內完成(例如解析
location.hash),動態修改 DOM 結構而產生。數據流不經過伺服器,使傳統的後端 WAF 難以偵測
二、 CSRF:假冒身分的跨站請求偽造
如果說 XSS 是偷走我們的鑰匙,那麼 跨站請求偽造(Cross-Site Request Forgery, CSRF) 就像是「趁我們還在店裡時,假冒我們的名義叫店員刷我們的卡」
CSRF 武器化了瀏覽器的「環境授權機制」(Ambient Authority) — 即瀏覽器在發送 HTTP 請求時,會自動夾帶目標網站對應域名的 Cookie。攻擊者完全不需要執行任何腳本,而是利用網站對使用者登入狀態(Session)的信任,在使用者不知情的情況下發起非預期的狀態變更請求
武器化手段與攻擊條件
攻擊者常見的誘發手段包括:
- 自動 GET 請求: 隱藏在 HTML 標籤中,如
<img src="[https://bank.com/transfer?to=attacker&amount=10000](https://bank.com/transfer?to=attacker&amount=10000)" /> - 自動 POST 請求: 在惡意網頁放置隱藏表單,並透過 JavaScript 在載入時自動
.submit()
CSRF 成功必須同時滿足三個條件:目標站點存在驗證缺陷、用戶處於登入狀態、用戶被引誘進入惡意網頁
三、 XSS vs CSRF 終極對比
為了更清晰地界定這兩大威脅,我們可以從關鍵維度進行對照:
四、 縱深防禦:構建穩固的安全陣線
安全不是單一的開關,而是層層堆疊的過濾器。面對複雜的攻擊手段,我們必須採取 縱深防禦 (Defense in Depth) 策略
1. XSS 防禦:重塑執行邊界
- 輸出編碼 (Output Encoding): 防禦 XSS 的核心手段。實施「字元實體編碼」(如將 < 轉為
<),將具有語法功能的符號轉化為「被動數據佔位符」。這種中和(Neutralization)機制能確保任何注入內容僅被視為純文本 - HttpOnly Cookie: 架構師預防 Session 竊取的硬性標準。強制設定
HttpOnly屬性後,JavaScript 將徹底失去對該 Cookie 的存取權(document.cookie讀不到),即使網站不幸爆發 XSS,攻擊者也無法盜取這把萬能鑰匙 - 內容安全政策 (CSP): 基於「零信任模型」,透過白名單機制明確告訴瀏覽器哪些來源的腳本允許執行,從源頭限制內聯腳本(Inline Scripts)與非法資源載入
- 現代框架與 CI/CD 紀律: React 與 Angular 等框架預設會進行自動轉義(Escaping)。團隊應在 CI/CD 流程中加入 Linting 規則,嚴格審查如
dangerouslySetInnerHTML或innerHTML等高風險 API
2. CSRF 防禦演進與高級對抗
SameSite Cookie 的機理與模式
SameSite 屬性是現代瀏覽器對抗 CSRF 的強力救星:
- Strict: 最高安全等級,完全禁止任何第三方跨站夾帶 Cookie。雖安全但可能影響體驗(如從外部連結點入需重新登入)
- Lax (預設標準): 允許頂層導航(如
<a href>)攜帶 Cookie,但阻擋 POST 表單等跨站狀態變更請求 - None: 不施加限制,但必須同時標記
Secure屬性(僅限 HTTPS 傳輸)
⚠️ 專家筆記:SameSite 的潛在盲點與陷阱
- Lax 兩分鐘窗口 (Lax-by-default-2-minute): Chrome 與 Firefox 對於「未明確指定」SameSite 的新寫入 Cookie,在前 2 分鐘(120秒)內仍允許 Top-level 的跨站 POST 請求。開發者必須明確指定
SameSite=Lax才能消除此空窗期 - Method Override 繞過: 若後端支援
_method=DELETE或_method=POST等參數轉換,攻擊者可以透過 Lax 模式允許的 GET 請求來觸發破壞性的狀態變更 - 子網域攻擊 (CVE-2022–21703 Grafana 案例): SameSite 的防禦邊界是「站點 (Site, eTLD+1)」而非「來源 (Origin)」。若攻擊者控制了
attacker.example.com,對主站api.example.com而言仍屬於 Same-site,SameSite Cookie 依然會發送!
超越 SameSite 的全域 CSRF 防護
針對高敏感業務(如金融轉帳)或子網域風險場景,必須疊加額外驗證:
- CSRF Token: 伺服器生成隨機且不可預測的加密字符串,要求前端發送敏感請求時必須在 Header 或 Form 中攜帶。因為攻擊者無法跨站讀取該 Token,能完美補足 SameSite 的盲點
- Double Submit Cookie: 適用於 SPA 或無狀態(Stateless)架構。利用 Cookie 僅能由同域名讀寫的特性,在 Cookie 與請求參數中各放一份相同隨機值,由伺服器比對一致性
- 嚴格的 Content-Type 檢核: 攻擊者可能構造
text/plain的 Simple Request 來繞過 CORS 預檢 (OPTIONS preflight)。後端必須實施嚴格的 MIME 檢核,拒絕非預期的複合 Content-Type
五、 維運紀律與終極心法
確保 Web 應用程式安全是一項持續性的架構紀律:
- 方法冪等性規範: 嚴禁使用 GET 請求執行任何狀態變更操作(Non-idempotent methods)
- 供應鏈審核: 使用
npm audit等工具持續監控第三方套件,避免 Stored XSS 透過相依項注入 - 自動化態勢感知: 定期使用 OWASP ZAP 進行動態掃描,並在 CI/CD 階段強制執行靜態程式碼分析 (SAST)
對於一般使用者而言,在使用完敏感網站(如網路銀行)後養成定期點擊「登出」的習慣,並保持對陌生連結的警覺,就能消除大部分的 CSRF 攻擊條件
兩句核心金句內化資安意識
- XSS 是「騙用戶執行」惡意程式碼
- CSRF 是「騙瀏覽器發送」惡意請求
在網路世界中,安全不是一個檢查清單,而是一種持續的紀律。理解漏洞原理只是起點,將縱深防禦策略落實在每一行程式碼與每個架構決策中,才是保護數位生活最穩固的ㄇ城牆!