CSP Header 是必要的嗎?
CSP Header 是必要的嗎?
作為軟體公司的技術管理者,您可能經常遇到資安掃描報告中出現「CSP Header Not Set」的警告。本文將深入探討 Content Security Policy (CSP) 的必要性、實作方式,以及為什麼資安掃描工具會將其視為必要檢查項目。
CSP 是否為強制性要求?
答案是:不是強制性的,但強烈建議實施。
CSP 的實施優先級取決於您的應用場景:
高優先級場景
- 面向公眾的網站:直接暴露於網際網路的應用
- 敏感資料處理:涉及金融、醫療、個人隱私資料的系統
- 企業級應用:即使是內部系統,也需要多層防護
- 合規要求:PCI DSS、GDPR 等法規標準的要求
- 現代化應用:大量使用 JavaScript 框架的 SPA 應用
可彈性處理的場景
- 純靜態展示頁面:無用戶互動的資訊頁面
- 開發測試環境:但生產環境仍建議加入
- 遺留系統:可採用漸進式實施策略
CSP 的核心價值
Content Security Policy 作為瀏覽器的安全機制,提供以下防護能力:
- XSS 攻擊防護:阻止惡意腳本注入和執行
- 資源來源控制:限制可載入的 JavaScript、CSS、圖片等資源
- 點擊劫持防護:防止網頁被嵌入惡意框架
- 資料外洩防護:控制資料傳輸的目標位址
實務部署指南 基礎設定範例
Content-Security-Policy: default-src 'self';
style-src 'self';
script-src 'self';
img-src 'self' data:;
frame-ancestors 'none';
form-action 'self';
部署驗證方法 1. 瀏覽器開發者工具檢查
- 開啟目標網站
- 按 F12 開啟開發者工具
- 切換至 Network 分頁
- 重新載入頁面
- 檢查主要請求的 Response Headers 是否包含 CSP 標頭
2. 命令列檢測
curl -i https://your-domain.com
查看回應標頭中的 Content-Security-Policy
欄位
3. 線上檢測工具
使用 Security Headers 進行全面的安全標頭檢測
資安掃描軟體的判斷邏輯 檢測機制
資安掃描工具主要透過 HTTP Response Headers 分析來判斷:
檢測邏輯:
IF (HTTP Response 中無 Content-Security-Policy 標頭) THEN
標記為 "CSP Header Not Set"
風險等級 = Medium
建議 = 實施 CSP 政策
END IF
不同工具的評估標準
掃描工具 | 檢測範圍 | 風險等級 | 主要考量 |
---|---|---|---|
OWASP ZAP | 所有 Web 回應 | Medium | OWASP Top 10 合規 |
Nessus | 動態內容頁面 | Medium | 企業安全標準 |
Burp Suite | JavaScript 執行頁面 | Medium-High | 實際攻擊向量 |
Security Headers | 所有 HTTP 回應 | Warning | 最佳實務建議 |
為什麼採用統一標準?
- 預防性安全原則:假設所有 Web 應用都存在潛在風險
- 自動化檢測需求:無法動態判斷應用的複雜度和風險等級
- 標準化合規要求:遵循 OWASP、NIST 等安全框架
- 成本效益考量:統一實施比個案評估更具經濟效益
分階段實施策略 階段一:觀察模式 (Report-Only)
Content-Security-Policy-Report-Only: default-src 'self'
- 收集違規報告
- 分析現有應用的資源載入模式
- 評估實施影響
階段二:政策調整
- 根據報告調整 CSP 規則
- 處理第三方服務整合
- 測試關鍵功能完整性
階段三:正式部署
Content-Security-Policy: default-src 'self'; script-src 'self'
- 移除 Report-Only 模式
- 監控應用運行狀況
- 建立長期維護機制
技術決策建議 風險評估矩陣
高風險應用(立即實施)
- 處理用戶敏感資料
- 面向公眾的商業應用
- 金融、醫療相關系統
中風險應用(計劃實施)
- 企業內部系統
- 有限用戶群的應用
- 資料敏感度中等的系統
低風險應用(可延後實施)
- 純展示型網站
- 測試開發環境
- 無用戶互動的靜態頁面
實施成本考量
開發成本
- CSP 政策設計:2-4 MD
- 測試和調整:4-8 MD
- 文件和維護:1-2 MD
維護成本
- 定期政策檢視
- 第三方服務整合調整
- 安全事件回應機制
綜合常見修改工作量評估
- 小型專案:2-4 MD
- 中型專案:4-8 MD
- 大型專案:14-28 MD
耗時最多時間花在
- 找出所有內聯樣式和事件
- 測試第三方函式庫相容性
- 調整動態樣式邏輯
結論與建議
CSP Header 雖非法律強制要求,但在現今的網路威脅環境下,它是一個投資回報率極高的安全措施。資安掃描軟體將其標記為必要檢查項目,反映了業界對於「縱深防禦」安全理念的共識。
建議行動方案:
- 立即行動:為面向公眾的生產環境實施基礎 CSP
- 漸進部署:採用 Report-Only 模式進行測試和調整
- 持續優化:建立 CSP 政策的定期檢視和更新機制
- 團隊培訓:確保開發團隊理解 CSP 的原理和最佳實務
記住,安全不是一次性的實施,而是持續的過程。CSP 作為現代 Web 安全架構的重要組成部分,值得每個技術團隊認真對待和實施。
ZAP 與 Angular 程式碼實務
以下為實際通過ZAP 運作的 CSP header 內容, 注意到它未使用了 unsafe-inline, 增加了 fallback 處理(frame-ancestors & form-action)。
default-src 'self'; style-src 'self'; script-src 'self'; img-src 'self' data:; frame-ancestors 'none'; form-action 'self';
要讓 Angular 應用能使用最嚴格的 CSP ('self'
only),需要進行以下修改:
1. Angular 建置配置修改 修改 angular.json
{
"projects": {
"your-app": {
"architect": {
"build": {
"options": {
"extractCss": true,
"optimization": true,
"buildOptimizer": true,
"aot": true,
"vendorChunk": true,
"commonChunk": true,
"namedChunks": false
},
"configurations": {
"production": {
"extractCss": true,
"optimization": {
"scripts": true,
"styles": {
"minify": true,
"inlineCritical": false
}
}
}
}
}
}
}
}
}
關鍵設定:
"extractCss": true
- 將所有樣式提取到外部檔案"inlineCritical": false
- 禁用關鍵 CSS 內聯
2. 移除內聯事件處理器 修改 HTML 模板
❌ 避免使用:
<button onclick="doSomething()">按鈕</button>
<div onmouseover="showTooltip()">懸停</div>
✅ 改為:
<button (click)="doSomething()">按鈕</button>
<div (mouseover)="showTooltip()">懸停</div>
3. 處理動態樣式 使用 Angular Renderer2
❌ 避免直接操作 style:
// 不要這樣做
element.style.color = 'red';
element.setAttribute('style', 'color: red;');
✅ 使用 Renderer2:
import { Renderer2, ElementRef } from '@angular/core';
constructor(private renderer: Renderer2, private el: ElementRef) {}
// 設定樣式
this.renderer.setStyle(this.el.nativeElement, 'color', 'red');
// 或使用 CSS 類別
this.renderer.addClass(this.el.nativeElement, 'red-text');
使用 CSS 類別替代內聯樣式
❌ 避免:
@Component({
template: `<div [style.color]="dynamicColor">文字</div>`
})
✅ 改為:
@Component({
template: `<div [class.red-text]="isRed" [class.blue-text]="isBlue">文字</div>`,
styles: [`
.red-text { color: red; }
.blue-text { color: blue; }
`]
})
4. 第三方函式庫處理 檢查並替換有問題的函式庫
# 檢查哪些函式庫使用內聯樣式
npm audit --audit-level moderate
常見問題函式庫替代方案
- Bootstrap: 使用
ng-bootstrap
而非原生 Bootstrap - jQuery: 盡量用 Angular 原生方法替代
- 圖表函式庫: 選擇支援 CSP 的版本(如 Chart.js 配置 CSP 模式)
5. 測試配置 本地測試 CSP
在 src/index.html
中暫時加入:
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; style-src 'self'; script-src 'self'; img-src 'self' data:;">
6. 建置和部署
# 使用 production 建置
ng build --configuration=production
# 檢查生成的檔案中是否有內聯內容
grep -r "style=" dist/
grep -r "onclick=" dist/
7. 段階式驗證 階段 1:先測試樣式
Content-Security-Policy: default-src 'self'; style-src 'self'; script-src 'self' 'unsafe-inline'; img-src 'self' data:;
階段 2:再測試腳本
Content-Security-Policy: default-src 'self'; style-src 'self'; script-src 'self'; img-src 'self' data:;
參考網站