---

title: Content Security Policy(CSP)实战:脚本隔离、资源白名单与违规上报

tags:

  • CSP
  • XSS防护
  • 资源白名单
  • 报告上报
  • 安全策略
  • 浏览器安全

description: 以生产可用的方式部署 CSP,覆盖脚本隔离、资源白名单配置、nonce/hash 策略与违规上报,实现高强度前端安全防护

categories:

  • 文章资讯
  • 技术教程

---

Content Security Policy(CSP)实战:脚本隔离、资源白名单与违规上报

技术背景

CSP 通过对脚本、样式、媒体、框架等资源的来源进行白名单限制,降低 XSS 与数据注入风险。结合 nonce/hashstrict-dynamicframe-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,必要时采用哈希白名单
  • 对第三方脚本做网关与审计,渐进引入
  • 结合报告端做观察与调参与回滚策略

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部