面试或日常工作常见的 4 个 CSP 问题

1,126 阅读2分钟

th.webp

公众号:JavaScript与编程艺术

1. 设置 CSP 有几种渠道?

答:服务端设置和客户端设置。即 HTTP Header 和 HTTP meta 标签。

HTTP Header:

Content-Security-Policy: img-src 'self' data: blob:;

HTTP meta 标签:

<meta http-equiv="Content-Security-Policy" content="img-src 'self' data: blob:" />

2. 二者有何区别?如何选择?哪个优先级更高?

区别

设置方式安全性范围兼容性
HTTP Header更安全所有域名所有指令都可配置
HTML meta篡改风险单个文档,meta 标签之后某些会被忽略

会被忽略的指令:Content-Security-Policy-Report-Only, report-uri, frame-ancestors, sandbox

如何选择

出于安全性考虑应该优先选择 HTTP Header。

优先级

从先后顺序来看:HTTP Header > HTTP meta 标签。

  • 不同规则合并。
  • 相同规则以更严格为准,即『可以更严格但是不能更宽松』。

举例来说,一旦 HTTP Header 指定了 img-src https: data:,在 HTTP meta 中改成 img-src https: (更严格因为仅允许加载来自 https 的图片)可以生效,但是若改成更宽松 img-src https: data: blob: 则不会生效。

改成 img-src https: 新插入data:image/png;base64,xyz... 图片将报错(已展示的图片不受影响):

Refused to load the image 'data:image/png;base64,xyz...' because it violates the following Content Security Policy directive: "img-src https:".

3. 'self' 是什么意思?包含 data:blob: 吗?

首先 self 必须加 引号。img-src selfimg-src "self" 都是错误的。

self 是指允许加载来自同源(same origin)的资源。不包含 data:blob:

同源:协议 & domain 或 subdomain & 端口号。

4. * 通配符用法

* 可以用于任何部位,scheme、domain 和 port。

  • http://* 等同于 http:
  • http: 等同于 http: + https协议升级自动包含,再比如 ws:wss:
  • http://*.example.com 匹配所有子 domain 和对应的 https
    • http://foo.example.com
    • http://foo.bar.example.com
    • https://foo.example.com
    • https://foo.bar.example.com
    • ...

有误理解:

  • *.example.com 错误应该是 http://*.example.com
  • http://*.example.com 匹配端口号 80 443,但不匹配其他端口。

其他知识

  • 一旦指令被 parse 则后续的修改都不会生效。具体来说解析后对 meta 元素的内容属性进行的任何修改都将被忽略。这意味着一旦 meta http-equiv 标签被处理,对其内容的进一步修改将不会产生效果。

参考

Difference Between HTTP Headers and Meta http-equiv for Content Security Policy (CSP)