從日常生活看網站攻擊:你家大門的兩種威脅
想像你家大門有兩種被闖入的方式。第一種是小偷在你的鑰匙上偷偷複製了一把(XSS 攻擊),他可以隨時用假鑰匙進入你家,翻找值錢的東西。第二種是有人假冒你的身份打電話給鎖匠,要求換鎖(CSRF 攻擊),鎖匠以為是你本人的指示,照做之後你反而被鎖在門外。
這兩種攻擊手法在網站世界中極為常見,卻經常被忽略。根據 OWASP Top 10 安全風險報告,注入攻擊與跨站請求偽造長年名列前茅。如果你的企業網站缺乏對應防護,等同於把大門敞開邀請駭客進來。
跟客戶聊的時候,老闆通常會問「我們網站又不是銀行,需要這麼麻煩嗎?」實際上,我們處理過的中壢一間製造業客戶官網,被植入 XSS 偷後台 Cookie 之後,攻擊者拿到管理員權限把網站首頁換成色情賭博廣告——SEO 排名一週內全部消失,後續花了三個月才回得來。了解網站資安防護基礎是每位網站擁有者的必修課。
什麼是 XSS 跨站腳本攻擊?
XSS(Cross-Site Scripting) 是指攻擊者將惡意的 JavaScript 程式碼注入到網頁中,當其他使用者瀏覽該頁面時,瀏覽器會自動執行這段惡意程式碼。攻擊者可以藉此竊取使用者的 Cookie、Session Token,甚至冒充使用者執行操作。
XSS 攻擊主要分為三種類型:
- 反射型 XSS(Reflected XSS):惡意腳本藏在 URL 參數中,伺服器將參數內容直接回傳到頁面上。攻擊者通常透過釣魚信件引誘使用者點擊含有惡意參數的連結。
- 儲存型 XSS(Stored XSS):惡意腳本被永久儲存在伺服器的資料庫中(例如論壇留言、用戶個人簡介),所有瀏覽該頁面的使用者都會受害,危害範圍最大。
- DOM 型 XSS(DOM-based XSS):惡意腳本不經過伺服器,直接透過前端 JavaScript 操作 DOM 來執行,更難被伺服器端的防護機制偵測。
什麼是 CSRF 跨站請求偽造?
CSRF(Cross-Site Request Forgery) 是攻擊者利用使用者已登入的狀態,誘使瀏覽器向目標網站發送未經授權的請求。因為瀏覽器會自動附帶該網站的 Cookie,伺服器無法分辨這個請求是使用者主動發起,還是被攻擊者冒充的。
舉例來說,你在 A 銀行網站保持登入狀態,同時開了另一個惡意網頁。那個惡意網頁暗中向 A 銀行發送一個轉帳請求,因為瀏覽器自動帶上了你的登入 Cookie,銀行伺服器會認為這是你本人的操作而執行轉帳。
XSS 防護策略
輸出編碼(Output Encoding)
最基本也最重要的防護是在將使用者輸入的內容輸出到 HTML 頁面時,進行適當的編碼。將 <、>、&、" 等特殊字元轉換為對應的 HTML Entity,讓瀏覽器將它們視為純文字而非程式碼。
現代框架如 Laravel 的 Blade 模板引擎,預設使用雙大括號語法時就會自動進行 HTML 編碼,大幅降低了 XSS 風險。
內容安全政策(Content Security Policy)
CSP 是一個強大的 HTTP 回應標頭,它告訴瀏覽器「只允許執行來自特定來源的腳本」。即使攻擊者成功注入了惡意腳本,瀏覽器也會因為腳本來源不在白名單中而拒絕執行。
設定 CSP 時需要特別注意避免使用 unsafe-inline 和 unsafe-eval,因為這會大幅削弱 CSP 的防護效果。
輸入驗證與清理
在伺服器端對所有使用者輸入進行嚴格的白名單驗證——只允許預期的字元和格式通過。如果需要允許使用者輸入富文本(如部落格編輯器),應使用經過安全審計的 HTML 清理套件,移除所有潛在危險的標籤和屬性。
HttpOnly 與 Secure Cookie
將 Session Cookie 設定為 HttpOnly,JavaScript 就無法透過 document.cookie 讀取它,即使 XSS 攻擊成功,也無法直接竊取 Session。搭配 Secure 旗標確保 Cookie 只在 HTTPS 連線中傳送,進一步提升安全性。關於 HTTPS 的設定細節,可以參考 SSL/TLS 進階指南。
CSRF 防護策略
CSRF Token 機制
最經典的防護方式是在每個表單中嵌入一個隨機產生的 Token。使用者提交表單時,伺服器會驗證這個 Token 是否與 Session 中儲存的值一致。因為攻擊者無法取得這個 Token(受同源政策保護),偽造的請求會因為缺少有效 Token 而被拒絕。
Laravel 框架內建了 CSRF 防護機制,只需在表單中加入 @csrf 指令即可。
SameSite Cookie 屬性
SameSite 是較新的 Cookie 屬性,它控制瀏覽器在跨站請求中是否附帶 Cookie:
- Strict:完全不允許跨站請求攜帶 Cookie,防護最嚴格但可能影響使用體驗(例如從外部連結點進來時會需要重新登入)。
- Lax:允許安全的頂層導航(如點擊連結)攜帶 Cookie,但阻止跨站的 POST 請求,是目前推薦的預設值。
- None:不限制,但必須搭配 Secure 旗標使用。
驗證 Referer 與 Origin 標頭
伺服器可以檢查 HTTP 請求的 Referer 或 Origin 標頭,確認請求是否來自自己的網域。雖然這不是最可靠的防護(某些情況下標頭可能被省略),但作為額外的防護層仍有價值。
框架的內建防護機制
現代 Web 框架普遍內建了 XSS 與 CSRF 的基礎防護,大幅降低了開發者犯錯的機會:
- 模板引擎自動編碼:Laravel Blade、React JSX、Vue Template 都會預設對變數輸出進行 HTML 編碼
- CSRF Token 自動管理:Laravel 為每個 Session 自動產生 CSRF Token,並在 middleware 層自動驗證
- Cookie 安全設定:框架通常提供集中的 Cookie 設定,方便一次啟用 HttpOnly、Secure、SameSite
然而,框架的防護並非萬能。開發者仍需注意避免使用未編碼的原始輸出(如 Blade 的 {!! !!}),以及確保所有 API 端點也有適當的 CSRF 防護或替代的身份驗證機制。
老實說,我們在 code review 接手的舊專案時,最常看到的 XSS 漏洞就是「為了顯示 HTML 編輯器存的內容」直接用 {!! $content !!}。前工程師可能只是想偷懶,但這等於把 XSS 大門打開。正確做法是搭配 HTML Purifier 之類的清理套件先過濾。想了解更多 API 安全防護的細節,可以參閱我們的專題文章。
實務檢核清單
以下列出開發團隊應定期檢查的安全項目,建議搭配網站安全稽核清單一併使用:
XSS 防護檢查:
- 所有使用者輸入在輸出時是否經過適當編碼
- 是否已設定 Content Security Policy 標頭
- Cookie 是否已設定 HttpOnly 和 Secure 旗標
- 富文本編輯器是否使用安全的 HTML 清理機制
- 前端是否避免使用
innerHTML直接插入未經清理的內容
CSRF 防護檢查:
- 所有表單是否包含 CSRF Token
- AJAX 請求是否在標頭中傳送 CSRF Token
- Session Cookie 是否已設定 SameSite 屬性
- 重要操作(如刪除、轉帳)是否有額外的確認機制
結語:安全是一場持續的投資
XSS 與 CSRF 是兩種截然不同但同樣危險的攻擊手法。XSS 攻擊的是使用者的信任——在使用者信任的網站上執行惡意程式碼;CSRF 攻擊的是伺服器的信任——利用伺服器對已認證使用者的信任。
好消息是,現代框架已經提供了強大的內建防護。開發者需要做的,是理解這些防護機制的原理,確保正確使用它們,並在框架防護不足的地方補上額外的安全措施。
如果你的企業正在規劃或改版網站,安全性應該從架構設計階段就被納入考量,而不是上線後才亡羊補牢。元伸科技的 客製化網頁設計 與客製化系統開發團隊在每個專案中都將安全防護列為核心需求,從第一天起就建立完善的安全防線。
需要協助稽核既有網站、或重新建置安全的企業系統嗎?
📞 03-366-1000 | 🌐 www.ozchamp.com | 免費諮詢 24hr 回覆