iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
Modern Web

現代函式庫與JavaScript的關係系列 第 17

Day 17 | XSS、CSRF、權限控管、稽核紀錄搭配前端框架是否有減輕負擔

  • 分享至 

  • xImage
  •  

先給結論:這四件事的「框架相關性」差很多,前兩個有差,後兩個基本沒差。

項目 框架有沒有差 原因
XSS(Cross-Site Scripting,跨站腳本攻擊) 差很多 它發生在「模板渲染」這層,而模板引擎就是框架的核心
CSRF(Cross-Site Request Forgery,跨站請求偽造) 差在「有沒有內建」 需要伺服器發 token,所以差異主要在後端框架
權限控管 幾乎沒差 這是應用邏輯,框架只給你一個掛載點
稽核紀錄(Audit Log) 完全沒差 框架不管這件事

一、XSS:這裡的框架差異最大

三個框架都預設會轉義插入的文字,但兩件事不同:逃生門的名字,以及有沒有做淨化

框架 預設行為 逃生門(繞過保護的寫法) 名字有警告嗎
React {} 內的值自動轉義 dangerouslySetInnerHTML ✅ 名字直接罵你
Vue {{ }} 自動轉義 v-html ❌ 完全看不出危險
Angular 自動轉義+主動淨化 bypassSecurityTrustHtml ✅ 有警告
Svelte 自動轉義 {@html ...} ❌ 沒警告

Angular 是四個裡最嚴格的,因為它多做了一層別人沒做的事:

  • 轉義(escape):把 < 變成 &lt;,內容原樣顯示但瀏覽器不執行。React、Vue、Svelte 做的是這個。

  • 淨化(sanitize)真的去解析那段 HTML,把危險的部分挑掉(拿掉 <script>、拿掉 onerror=),保留安全的標籤。Angular 的 DomSanitizer 做的是這個。

差別在於:如果你要讓使用者貼「有格式的文字」(例如富文本編輯器的內容),React 和 Vue 只給你「全轉義」或「全放行」兩個極端,中間那層要自己裝 DOMPurify;Angular 內建就有。

(順帶一提,你的 next-one-mainpackage.json 裡有 isomorphic-dompurify,那就是在補這一層。)

但有三個地方所有框架都幫不了你

a. URL 屬性

<a href={userInput}>點我</a>

白話講:使用者如果輸入 javascript:alert(1),這行就變成可執行的連結。React 只會在 console 印警告,不會阻止,Vue 和 Svelte 更是完全不管。自動轉義只管「文字內容」,不管「屬性值的語意」。

b. CSS 注入與 <style> 標籤

框架的轉義機制對 CSS 完全沒有概念。

c. 沒有經過框架的注入

這一點跟你被駭那件事直接相關。 你那個 <script src="data:text/javascript;base64,..."> 是在伺服器回應 HTML 的當下被插進 <head> 的——它根本沒有經過 React 的渲染流程,所以 React 的自動轉義從頭到尾沒有機會介入。

框架的 XSS 防護只能保護「從框架流進去的資料」。 一旦攻擊者能改 HTTP 回應本身,換哪個框架都一樣。


二、CSRF:差別在「誰負責發 token」

框架 有沒有內建 CSRF 防護
Next.js 一般 API Route 沒有;Server Actions 有 Origin/Host 比對
Nuxt 沒有,要裝 nuxt-security
Angular HttpClientXsrfModule,但要後端配合放 cookie)
Rails/Django/Laravel 有,而且預設開啟

關鍵認知:CSRF 主要是後端框架的責任,不是前端框架的。

因為 CSRF token 必須由伺服器產生、由伺服器驗證,前端只是負責把它帶上。React、Vue 是 UI 層,它們沒有「伺服器」可以發 token。

Angular 之所以有,是因為它是全功能框架,內建了 HTTP client,所以順便把「自動從 cookie 讀 token 塞進 header」這件事包進去。

而且現在主流解法已經跟框架無關了——SameSite cookie 屬性:

Set-Cookie: session=xxx; SameSite=Lax; Secure; HttpOnly

白話講:這行告訴瀏覽器「從別的網站發過來的請求,不要帶這個 cookie」。這是瀏覽器層的防護,換什麼框架都一樣有效,也是為什麼新專案對傳統 CSRF token 的依賴降低了。


三、權限控管:框架只給掛載點,而且前端的不算安全

各框架提供的「掛載點」名字不同,但做的事一樣:

  • Next.js → middleware.js

  • Angular → Route Guards(路由守衛)

  • Vue Router → navigation guards(導航守衛)

  • React Router → loader 或自己包一層 <RequireAuth>

但這裡有一句比框架比較重要一百倍的話:

前端的權限控管只是 UI,不是安全。

任何前端的守衛都可以被繞過——打開 DevTools 改變數、直接用 curl 打你的 API、把 JS 改掉再執行。前端的權限判斷只是「不要讓使用者看到他不該看的按鈕」,真正的守門員必須在後端。

這一點正好對上你專案的問題/api/website-content 這個端點對全世界公開回傳 130 KB 的內部資訊。前端有沒有藏起來完全不重要,因為攻擊者是直接打那個網址。

所以權限控管要問的不是「我的框架怎麼做」,而是**「每一個 API 端點都有自己驗過身分嗎」**。


四、稽核紀錄:框架完全不管

這個沒有框架差異,因為它根本不在框架的職責範圍。稽核紀錄屬於三個地方:

  • 後端應用層:誰在什麼時間對什麼資源做了什麼操作,寫進 audit table

  • 資料庫層:觸發器(trigger)、或 CDC(Change Data Capture,變更資料擷取)

  • 基礎設施層:APM(Application Performance Monitoring)、log 聚合服務

前端框架連「使用者是誰」都只是暫存在記憶體裡,沒有資格當稽核來源——因為前端送上來的任何東西都可以被偽造。


總結

框架能幫你的,只有「資料從框架流進畫面」那一段(XSS)。
CSRF 是後端的事,權限控管是 API 的事,稽核是資料庫和基礎設施的事。

所以「換一個更安全的框架」這個想法,只在 XSS 這一項上有意義,而且效果有限。



上一篇
Day 16 | useMemo在React、Vue、Angular中的實現與効能最佳化
下一篇
Day 18:實戰 150+ commits 的三大編譯陷阱 — TypeScript 編譯錯誤、環境變數管理、React 記憶體洩漏
系列文
現代函式庫與JavaScript的關係21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言