安全策略和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")。