昨天同事反馈在公司项目中的创建视频商机页面,选择视频点击无反应,于是审查对应的页面发现有如下js报错
原因是最近公司项目服务迁移,在重新配置csp策略的时候遗漏了存放视频相关js的服务器地址。
1. CSP是什么
Content-Security-Policy(CSP)是HTTP响应标头的名称,现代浏览器使用它来增强文档(或网页)的安全性。Content-Security-Policy允许您限制诸如JavaScript,CSS或浏览器加载的几乎所有内容的资源。开发者可以创建并强制应用一些规则,管理网站允许加载的内容,那些资源可以被加载和执行,等同于设置了白名单,白名单之外的资源请求会报错,会使网站在默认情况下变得更加安全。
2. CSP可以缓解哪些类型的攻击?
CSP最初旨在减少跨站点脚本(XSS)攻击的攻击面,该规范的更高版本也可以防止其他形式的攻击,例如Click Jacking(点击劫持)。
3. CSP浏览器支持
从上图可以看到csp1.0版本已得到所有主要现代浏览器的支持,全球高达97.96%,中国达到87.09%,但Internet Explorer从10版本仅支持sandbox属性。
我们可以点击CSP浏览器测试来测试您的浏览器对csp的支持度。在这个测试页面我们可以测试您的浏览器对csp1.0甚至是3.0最新特性的支持情况。
4.CSP的分类
1.Content-Security-Policy 配置好CSP安全策略并启用后,不符合 CSP安全策略 的外部资源就会被阻止加载并在控制台报错显示。
2.Content-Security-Policy-Report-Only 响应头允许web开发人员通过监测(但不强制执行)政策的影响来尝试政策。这些违反报告由 JSON 文档组成通过一个HTTP POST请求发送到指定的URI。
Content-Security-Policy-Report-Only: default-src https:; report-uri /csp-violation-report-endpoint/
报告的JSON对象包括下面的数据:
| 属性名 | 含义 |
|---|---|
| document-uri | 发生违规的文档URI。 |
| referrer | 发生违规的文档referrer。 |
| blocked-uri | 被内容安全政策阻塞加载的资源的URI。如果被阻塞的URI与文档URI不同源,则被阻塞的URI被截断为只包含scheme(协议),host(域名),和port(端口)。 |
| violated-directive | 被违反的策略名。 |
| original-policy | Content-Security-Policy HTTP 头部所指定的原始策略。 |
| disposition | “执行”或“报告”取决于是使用Content-Security-Policy 头还是使用 Content-Security-Header-Report-Only 头。 |
5. CSP 使用方式
1. csp如何指定设置
CSP可以由两种方式指定: HTTP Header请求头 和 HTML页面的meta标签
1、在HTTP Header上使用(首选)
"Content-Security-Policy:" <policy-directive>
"Content-Security-Policy-Report-Only:" <policy-directive>
知乎官网设置的CSP策略。
2、在HTML页面的meta标签里面设置
<meta http-equiv="content-security-policy" content="策略">
<meta http-equiv="content-security-policy-report-only" content="策略">
当两种方式同时设置的时候,则会优先采用HTTP Header的定义策略。
2. CSP的语法
Content-Security-Policy的报头值的可以用一个或多个指令(如下定义)的组成,多个指令与分号分隔;
Content-Security-Policy:指令1 指令值1
策略与策略之间用分号隔开,例如
Content-Security-Policy:指令1 指令值1;指令2 指令值2;指令3 指令值3
在一条策略中,如果一个指令中有多个指令值,则指令值之间用空号隔开:
Content-Security-Policy:指令a 指令值a1 指令值a2
3.CSP 指令
| 属性名 | 含义 | CSP版本 |
|---|---|---|
| default-src | 定义针对所有类型(js/image/css/font/ajax/iframe/多媒体等)资源的默认加载策略,如果某类型资源没有单独定义策略,就使用默认的。 | 1.0 |
| script-src | 定义针对 JavaScript 的加载策略。 | 1.0 |
| style-src | 定义针对 style样式表 的加载策略。 | 1.0 |
| img-src | 定义针对 img图片 的加载策略。 | 1.0 |
| font-src | 定义针对字体的加载策略。 | 1.0 |
| media-src | 定义针对多媒体的加载策略,限制通过、或标签加载的媒体文件的源地址。 | 1.0 |
| object-src | 定义针对插件的加载策略,限制、、标签的源地址。 | 1.0 |
| frame-src | 定义用于加载框架的有效源。在CSP 2级中,不推荐使用frame-src,而推荐使用child-src指令。3.0版本已弃用 | 1.0 |
| child-src | 定义针对框架的加载策略,例如: ,。 | 2.0 |
| connect-src | 定义针对 Ajax/WebSocket 等请求的加载策略。不允许的情况下,浏览器会模拟一个状态为400的响应。 | 1.0 |
| sandbox | 定义针对 sandbox 的限制,相当于 的sandbox属性。 | 1.0 |
| report-uri | 告诉浏览器如果请求的资源不被策略允许时,往哪个地址提交日志信息。 | 1.0 |
| form-action | 定义针对提交的 form 到特定来源的加载策略。 | 2.0 |
| frame-ancestors | 定义用于 标签嵌入资源的有效来源的加载策略。将此指令设置为“ none”应大致等效于设置X-Frame-Options:DENY | 2.0 |
| plugin-types | 为通过和调用的插件定义有效的MIME类型。要加载,必须指定application / x-java-applet。 | 2.0 |
| base-uri | 定义一组允许的URL,这些URL可以在HTML基本标签的src属性中使用。 | 2.0 |
| report-to | 定义由Report-To HTTP响应标头定义的报告组名称。 | 3.0 |
| worker-src | 限制可能作为Worker,SharedWorker或ServiceWorker加载的URL。 | 3.0 |
| manifest-src | 限制可以加载应用程序清单的URL。 | 3.0 |
| prefetch-src | 定义请求预取和预呈现的有效源,例如通过带有rel =“ prefetch”或rel =“ prerender”的链接标签。 | 3.0 |
| navigate-to | 通过任何方式限制文档可以导航到的URL。例如,当单击链接,提交表单或调用window.location时。如果存在form-action,则对于表单提交,将忽略此指令。 | 3.0 |
4.CSP指令值
| 属性名 | 示例 | 描述 |
|---|
- | img-src * | 通配符,允许的任何URL除了 data: blob: filesystem: schemes. 'none' | object-src 'none' | 防止从任何来源加载资源。 'self' |script-src 'self' |允许从相同的来源(相同的协议,域名和端口号)加载资源。. data: | img-src 'self' data: | 允许加载 data: 协议,例如:base64编码的图片 domain.example.com | img-src domain.example.com |允许从指定的域名加载资源. *.example.com |img-src *.example.com | 允许从example.com下的任何子域加载资源。 cdn.com |img-src cdn.com | 仅允许通过指定的HTTPS域匹配的加载资源 https: |img-src https: | 仅允许在任何域上通过HTTPS加载资源 'unsafe-inline' | script-src 'unsafe-inline' | 允许使用内联源元素,例如样式属性,onclick或inline js、inline css等 'unsafe-eval' |script-src 'unsafe-eval' | 允许加载动态 js 代码,例如 eval() 'sha256-' | script-src 'sha256-xyz...' |如果内联脚本或CSS的哈希值与标题中指定的哈希值匹配,则允许执行该脚本。当前支持SHA256,SHA384或SHA512。CSP2.0版本 'nonce-' |script-src 'nonce-r@nd0m' | 如果脚本(例如:<script nonce =“ r @ nd0m”>)标签包含与CSP标头中指定的随机数匹配的随机数属性,则允许执行内联脚本或CSS。随机数应为安全的随机字符串,并且不应重复使用。 CSP2.0版本 'strict-dynamic' |script-src 'strict-dynamic' | 允许脚本通过脚本元素去加载其他脚本(例如,允许document.createElement('script'). CSP 3.0 'unsafe-hashes' |script-src 'unsafe-hashes' 'sha256-abc...' | 允许您在事件处理程序中启用脚本 (eg ). 但是不适用于 javascript: 和 inline
5.CSP如何在本地快速调试
我们可以借助Chrome插件——modheader来自定义设置响应头来测试我们设置的CSP指令,方便我们快速了解各个指令的方法功能,但是具体项目配置还是需要依据自己项目在后端配置相对应的CSP策略。
1.在当前页面打开modheader 设置我们的自定义的CSP请求头
2.刷新页面我们查看响应请求头可以看到设置成功
3.在浏览器console面板看到对应的报错信息
4.调试完记得清除设置的策略。
总结
合理的利用CSP的策略可以一定程度上的减少XSS的攻击,但不一定意味着XSS的消失。