Content Security Policy(CSP)实战:脚本隔离、资源白名单与违规上报技术背景CSP 通过对脚本、样式、媒体、框架等资源的来源进行白名单限制,降低 XSS 与数据注入风险。结合 `nonce`/`hash`、`strict-dynamic` 与 `frame-ancestors`,可实现高强度的前端安全防线。核心内容基础策略示例(HTTP 头)Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-<random>' 'strict-dynamic'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https:; connect-src 'self' https://api.example.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'self'; upgrade-insecure-requests; report-uri https://csp.example.com/report; Node/Express 设置示例import express from 'express'; import crypto from 'crypto'; const app = express(); app.use((req, res, next) => { const nonce = crypto.randomBytes(16).toString('base64'); res.setHeader('Content-Security-Policy', [ `default-src 'self'`, `script-src 'self' 'nonce-${nonce}' 'strict-dynamic'`, `style-src 'self' 'unsafe-inline'`, `img-src 'self' data: https:`, `font-src 'self' https:`, `connect-src 'self' https://api.example.com`, `frame-ancestors 'none'`, `base-uri 'none'`, `object-src 'none'`, `form-action 'self'`, `upgrade-insecure-requests`, `report-uri https://csp.example.com/report` ].join('; ') ); (res as any).localsNonce = nonce; next(); }); app.get('/', (req, res) => { const nonce = (res as any).localsNonce; res.send(`<!doctype html><html><head><meta charset="utf-8"/></head> <body> <script nonce="${nonce}">console.log('Secure inline script');</script> </body></html>`); }); app.listen(3000); Cloudflare Workers/边缘设置export default { async fetch(req) { const nonce = btoa(crypto.getRandomValues(new Uint8Array(16)).reduce((s, b) => s + String.fromCharCode(b), '')); const headers = new Headers({ 'Content-Security-Policy': [ `default-src 'self'`, `script-src 'self' 'nonce-${nonce}' 'strict-dynamic'`, `style-src 'self' 'unsafe-inline'`, `img-src 'self' data: https:`, `font-src 'self' https:`, `connect-src 'self' https://api.example.com`, `frame-ancestors 'none'`, `base-uri 'none'`, `object-src 'none'`, `form-action 'self'`, `upgrade-insecure-requests`, `report-uri https://csp.example.com/report` ].join('; ') }); const html = `<!doctype html><html><body><script nonce="${nonce}">console.log('Edge CSP');</script></body></html>`; return new Response(html, { headers }); } }; 违规上报与可观测性// 前端接收报告(Report-To) // Response header: // Report-To: {"group":"csp-endpoint","max_age":10800,"endpoints":[{"url":"https://csp.example.com/report"}]} // 服务端示例(Node) app.post('/csp/report', express.json({ type: 'application/reports+json' }), (req, res) => { console.log('CSP report', req.body); res.status(204).end(); }); 技术验证参数在 Chrome 128/Edge 130/Safari 17 环境下:非白名单脚本阻断率:100%非同源框架嵌入阻断率:100%报告上报成功率:≥ 95%误阻断率(合法资源):≤ 1%应用场景高安全站点与后台系统的脚本隔离第三方脚本管理与渐进白名单策略结合 SRI/SHA‑256 的资源完整性校验最佳实践使用 `nonce` 搭配 `strict-dynamic`,避免固定域名列表带来的绕过风险禁止 `unsafe-inline`/`unsafe-eval`,必要时采用哈希白名单对第三方脚本做网关与审计,渐进引入结合报告端做观察与调参与回滚策略

发表评论 取消回复