什么是CSP(内容安全策略)?如何配置?

1. 什么是 CSP?如何启动 CSP

2. 限制选项

答:

  1. CSP 的实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置。

CSP 大大增强了网页的安全性。攻击者即使发现了漏洞,也没法注入脚本,除非还控制了一台列入了白名单的可信主机。

两种方法可以启用 CSP。

一种是通过 HTTP 头信息的 Content-Security-Policy 字段。

另一种是通过网页的 <meta> 标签。

<meta http-equiv="Content-Security-Policy" content="script-src 'self';
     object-src 'none'; style-src cdn.example.org third-party.org;
     child-src https">

上面代码中,CSP 做了如下配置。

CSP 提供了许多限制选项

default-src 用来设置上面各个选项的默认值:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

有时,我们不仅希望防止 XSS,还希望记录此类行为。report-uri 就用来告诉浏览器,应该把注入行为报告给哪个网址。

Content-Security-Policy: default-src 'self'; ...; report-uri /csp_report;

上面代码指定,将注入行为报告给 /csp_report 这个 URL。

浏览器会使用 POST 方法,发送一个 JSON 对象,下面是一个例子:

{
  "csp-report": {
    "document-uri": "http://example.org/page.html",
    "referrer": "http://evil.example.com/",
    "blocked-uri": "http://evil.example.com/evil.js",
    "violated-directive": "script-src 'self' https://apis.google.com",
    "original-policy": "script-src 'self' https://apis.google.com; report-uri http://example.org/my_amazing_csp_report_parser"
  }
}

Content-Security-Policy-Report-Only

不执行限制,只记录违反限制的行为。

补充

补充:CSP 是浏览器侧的"白名单执行官",把"哪些资源可以执行"这件事交给浏览器决定,配合现代前端构建系统能挡住大部分 XSS。

常用指令速查

指令作用
default-src默认策略(兜底)
script-src允许加载 JS 的来源
style-src允许加载 CSS 的来源
img-src允许加载图片的来源
connect-src允许 AJAX / WebSocket / fetch 的目标
frame-src允许 iframe 的来源
object-src允许 <object> / <embed> 的来源
base-uri限制 <base> 标签
form-action限制表单提交的目标
frame-ancestors替代 X-Frame-Options,控制谁可以嵌入本页
report-uri / report-to违规上报地址

一个常见生产策略

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-RANDOM_NONCE' 'strict-dynamic';
  style-src 'self' 'unsafe-inline';
  img-src 'self' data: https:;
  connect-src 'self' https://api.example.com;
  frame-ancestors 'none';
  base-uri 'self';
  form-action 'self';

其中 RANDOM_NONCE 由服务端每次请求动态生成,前端在 <script nonce="..."> 中带上。

注意事项

  • 启用前先用 Report-Only 模式跑一段时间,看清楚哪些资源被拦
  • 配合 nonce 或 hash 比直接列白名单更稳
  • 不要为了图省事放开 'unsafe-inline' / 'unsafe-eval',那样 CSP 几乎失效

来源整理自:我的有道云笔记