前端安全
零信任安全模型:永不信任,始終驗證
2026年的前端安全形勢比以往任何時候都更加嚴峻。傳統的「城堡與護城河」安全模型已經徹底失效。零信任安全模型應運而生,其核心原則:
永不信任,始終驗證(Never Trust, Always Verify)
每一個請求、每一次互動都必須經過嚴格的身份驗證和授權檢查。不存在「可信區域」,不存在「隱式信任」。
傳統邊界安全 vs 零信任架構
| 維度 | 傳統邊界安全 | 零信任架構 |
|---|---|---|
| 信任模型 | 內網可信,外網不可信 | 所有請求均不可信 |
| 驗證方式 | 一次性登入驗證 | 每次請求獨立驗證 |
| 網路邊界 | 依賴防火牆/VPN | 無邊界,身份即邊界 |
| 攻擊面 | 突破邊界即可橫向移動 | 每步都需重新驗證 |
| 適用於 | 傳統單體應用 | 雲原生/微服務/微前端 |
傳統模型最大的問題:一旦攻擊者突破了網路邊界,就可以在內網自由橫向移動。
前端零信任:每個API請求都獨立驗證
前端是零信任架構中最關鍵的一環——前端程式碼執行在使用者瀏覽器中,是完全不可控的環境。
核心原則
- 無隱式信任:不因使用者已登入就信任後續所有請求
- 最小權限:每個請求只獲取完成該操作所需的最小權限
- 持續驗證:Token短期有效,頻繁刷新
- 假設已被攻破:設計時假設攻擊者已控制前端
請求級驗證範例
class ZeroTrustHttpClient {
private tokenManager: TokenManager;
private proofManager: DPoPProofManager;
async request(config: RequestConfig): Promise<Response> {
const token = await this.tokenManager.getValidToken();
const proof = await this.proofManager.generateProof(
config.method, config.url
);
const response = await fetch(config.url, {
method: config.method,
headers: {
'Authorization': `DPoP ${token}`,
'DPoP': proof,
'X-Request-ID': crypto.randomUUID(),
'X-Timestamp': Date.now().toString(),
},
body: config.body,
});
if (response.status === 401) {
await this.tokenManager.refreshToken();
return this.request(config);
}
return response;
}
}
Token安全:JWT最佳實踐
| 實踐 | 說明 | 風險等級 |
|---|---|---|
| 短期Access Token | 有效期≤5分鐘 | 🔴 關鍵 |
| HttpOnly Cookie儲存 | 防止XSS竊取 | 🔴 關鍵 |
| Refresh Token輪換 | 每次刷新頒發新Refresh Token | 🔴 關鍵 |
| Token綁定(DPoP) | Token與密鑰對綁定 | 🟡 重要 |
| Audience限制 | 限定Token使用目標 | 🟡 重要 |
DPoP:Token綁定證明
DPoP將Token與客戶端的密鑰對綁定。即使攻擊者竊取了Token,沒有對應的私鑰也無法使用:
class DPoPProofManager {
private keyPair: CryptoKeyPair | null = null;
async init(): Promise<void> {
this.keyPair = await crypto.subtle.generateKey(
{ name: 'ECDSA', namedCurve: 'P-256' }, false, ['sign']
);
}
async generateProof(method: string, url: string): Promise<string> {
const header = { typ: 'dpop+jwt', alg: 'ES256', jwk: await this.getPublicKey() };
const payload = {
htu: new URL(url).origin + new URL(url).pathname,
htm: method,
iat: Math.floor(Date.now() / 1000),
jti: crypto.randomUUID(),
};
return this.signJWT(header, payload);
}
}
執行時保護:CSP、Trusted Types與SRI
CSP嚴格模式
<meta http-equiv="Content-Security-Policy" content="
default-src 'none';
script-src 'strict-dynamic' 'nonce-abc123';
style-src 'self' 'nonce-abc123';
img-src 'self' https: data:;
connect-src 'self' https://api.example.com;
frame-src 'none';
object-src 'none';
require-trusted-types-for 'script';
report-uri /api/csp-report;
">
Trusted Types防XSS
Trusted Types API從根源上防止DOM XSS——要求所有DOM Sink只能接受經過策略驗證的「可信類型」:
if (window.trustedTypes) {
trustedTypes.createPolicy('default', {
createHTML: (input: string) => DOMPurify.sanitize(input, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'br'],
}),
createScript: () => { throw new Error('Blocked'); },
});
}
SRI子資源完整性
<script src="https://cdn.example.com/bundle.js"
integrity="sha384-oc5F5A5B7B6B8B9C0D1E2F3"
crossorigin="anonymous"></script>
微前端安全:沙箱隔離與權限控制
微前端架構下,多個子應用共享同一頁面,安全隔離至關重要。
子應用權限控制矩陣
| 權限 | 主應用 | 使用者中心 | 資料看板 | 營銷模組 |
|---|---|---|---|---|
| localStorage | ✅ 讀寫 | ✅ 讀寫前綴 | ❌ | ❌ |
| 路由跳轉 | ✅ 全部 | ✅ 自身路由 | ✅ 唯讀 | ✅ 自身路由 |
| API呼叫 | ✅ 全部 | ✅ /api/user | ✅ /api/data | ✅ /api/market |
| 全域狀態 | ✅ 讀寫 | ✅ 唯讀 | ✅ 唯讀 | ✅ 讀寫 |
供應鏈安全
# 檢查已知漏洞
npm audit --audit-level=high
# 驗證lockfile完整性
npm ci --ignore-scripts
# 生成SBOM
npx @cyclonedx/cyclonedx-npm --output-format json -o sbom.json
最佳實踐:每次CI建構都生成SBOM,並與已知漏洞資料庫自動比對。
零信任前端架構Checklist
認證與授權
- Access Token有效期≤5分鐘
- Refresh Token啟用輪換機制
- Token儲存在HttpOnly + Secure + SameSite=Strict的Cookie中
- 啟用DPoP Token綁定
執行時保護
- CSP策略設為
default-src 'none'白名單模式 - 啟用Trusted Types策略
- 所有CDN資源配置SRI
- 禁用
eval()、new Function()
供應鏈安全
-
npm audit整合到CI管線 - lockfile完整性校驗
- 每次建構生成SBOM
零信任不是產品,而是一種安全思維方式。 它要求我們重新審視前端應用中的每一個信任假設,將「預設信任」轉變為「預設拒絕,顯式允許」。
本站提供瀏覽器本地工具,免註冊即可試用 →
#零信任#前端安全#Token验证#CSP#微前端安全