安全策略和CSP
1)為什麼需要安全政策
現代前端和API取決於多種來源(CDN,分析,PSP,3 DS,聊天)。如果沒有嚴格的政策,XSS、點擊戳、數據泄露和會話劫持的風險就會增加。安全策略通過將瀏覽器轉換為「僅明確允許」模型(allow-list)來限制默認允許的內容。
2)基本支柱
CSP(內容安全策略)是允許的JS/CSS/媒體源和行為的集中「菜單」。
Trusted Types-類型級別的DOM-XSS保護。
SRI (Subresource Integrity)-控制腳本/樣式的完整性。
COOP/COEP/CORP-嚴格隔離源之間的上下文和資源。
Fetch Metadata(「Sec-Fetch-」)是用於跨站點查詢過濾的服務器解決方案。
CORS是跨域API訪問策略。
經典標題:HSTS,「X-Frame-Options」/「frame-ancestors」,「Referrer-Policy」,「Permission-Policy」,SameSite Cookie。
3)CSP: 基礎和原則
3.1指令(關鍵)
「default-src」是其余指令的默認值。
「script-src」是JS,nonce/hash,「strict-dynamic」,「report-sample」的來源。
「style-src」是CSS的來源;盡量減少「unsafe-inline」。
`img-src`, `font-src`, `media-src`, `object-src` (обычно `none`).
「connect-src」-網絡查詢(XHR/fetch/WebSocket)。
「frame-src」/「child-src」是第三方框架(PSP,3 DS)。
「frame-ancestors」-誰可以嵌入我們的網站(反點擊)。
「base-uri」是子菜單禁令「<base>」。
「form-action」-允許在哪裏設置形狀。
「upgrade-insecure-requests」,「block-all-mixed-content」是與HTTP/HTTPS混合的鬥爭。
「report-uri」/「report-to」-在哪裏泄露違規行為。
3.2 Nonce и hash
Nonce方法:在每個HTTP響應上生成加密隨機的「nonce」,添加到inline腳本「<script nonce=」……「>」和「script-src'nonce-……」。
Hash方法:固定的inline內容哈希。適用於靜態HTML,在揚聲器時不方便。
'strict-dynamic':僅信任裝有「可信」腳本(帶有nonce/hash)的腳本。無需在動態引導時列出目標域,但需要現代瀏覽器。
3.3禁令'unsafe-'
避免「unsafe-inline」,「unsafe-eval」。如果框架需要eval(例如dev中的源映射),則僅在dev上啟用。
對於樣式-使用「nonce」或「hash」,如果可能的話,不使用內線。
3.4嚴格的CSP(戰鬥基準)示例)
Content-Security-Policy:
default-src 'none';
base-uri 'self';
object-src 'none';
script-src 'self' 'nonce-{RANDOM}' 'strict-dynamic' https://www. googletagmanager. com;
style-src 'self' 'nonce-{RANDOM}';
img-src 'self' data: https://images. example-cdn. com;
font-src 'self' https://fonts. gstatic. com;
connect-src 'self' https://api. example. com wss://ws. example. com;
frame-src https://3ds. psp. com https://pay. psp. com;
frame-ancestors 'none';
form-action 'self' https://pay. psp. com;
upgrade-insecure-requests;
report-to csp-endpoint; report-sample
4) Trusted Types (DOM-XSS)
啟用指令: 「內容安全性政策:require-trusted-types-for'script」;trusted-types app default`.
在代碼('window。trustedTypes.createPolicy('app', { createHTML() {... } })`).
禁止不安全的分配('element.innerHTML =...`) без Trusted Types.
與框架集成(React/Angular/Vue):使用安全渲染API,避免危險的dangerouslySetInnerHTML。
5)SRI(CDN完整性)
對於外部"<script>/"<link>"使用"integrity="sha 256-"……crossorigin="anonymous""。
SRI補充而不是取代CSP。更新CDN版本時-更新哈希。
6)點擊夾克和框架
現代方法是「frame-ancestors」(取代過時的「X-Frame-Options」)。