内容安全策略 (CSP) 是一个补充的安全层,用于检测并削弱某些特定类型的攻击,这些攻击包括跨站脚本 (XSS) 和数据注入攻击等。无论是数据盗取、网站内容污染还是散发恶意软件,都用到了这些攻击手段。
CSP 被设计成完全向后兼容(除CSP2 有明确提及不是完全向后兼容)。不支持CSP的浏览器也能与实现了CSP的服务器正常合作,反之亦然:不支持 CSP 的浏览器只会忽略它,如常运行,默认为网页内容使用标准的同源策略。如果网站不提供 CSP 头部,浏览器也使用标准的同源策略。
1 配置CSP的两种方式
- 为服务端响应设置:
Content-Security-PolicyHTTP头部 ( 有时会看到一些关于X-Content-Security-Policy头部的说法, 那是旧版本,你无须再如此指定它)。 - 为页面指定meta标签:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
2 CSP可以减弱的两种攻击
- XSS
通过指定哪些来源下的脚本是可以被浏览器执行的(这些来源被称为有效域),服务器管理者减少或消除了XSS攻击的载体。CSP兼容的浏览器只会执行从白名单域获取到的脚本文件,忽略所有的其他脚本 (包括内联脚本和HTML的事件处理属性)。
作为一种终极防护形式,始终不允许执行脚本的站点可以选择全面禁止脚本执行。
- packet sniffing attack
Strict-Transport-Security HTTP头部确保连接它的浏览器只使用加密通道。3 CSP的具体使用
配置内容安全策略的具体做法:为请求页面的响应添加 Content-Security-Policy HTTP首部,并配置相应的值。这样就可以控制用户代理(浏览器等)可以为该页面获取哪些资源。比如一个可以上传文件和显示图片的页面,是可以允许图片来自任何地方的,但却限制表单的action属性只可以赋值为指定的端点。一个设计良好的内容安全策略应该可以有效的保护页面免受跨站脚本攻击。本文阐述如何构造这样的首部,并提供了一些例子。
- CSP首部配置:
Content-Security-Policy: policy
包含 default-src 或者 script-src 指令来防止内联脚本运行, 并杜绝eval()的使用。 包含 default-src 或 style-src 指令去限制来自一个 <style> 元素或者style属性的內联样式。
- 具体示例:
- Content-Security-Policy: default-src 'self' 页面所有资源都必须来自自身的域(不包括子域)
- Content-Security-Policy: default-src 'self' *.trusted.com 页面资源可以来自指定的可信域(包括可信域的子域)
- Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com 页面所有的图片资源可以是任意域,但音频、视频必须来源于指定的media1.com域;页面上所有的脚本必须是来自于指定主机服务器(userscripts.example.com)上可信的代码
- Content-Security-Policy: default-src https://onlinebanking.jumbobank.com 仅允许通过HTTPS方式并仅从onlinebanking.jumbobank.com域名来访问文档
- Content-Security-Policy: default-src 'self' *.mailsite.com; img-src * 图片允许从任何地方加载,但其它只能在指定域中加载
4 策略报告模式
为方便部署,CSP可以部署为报告(report-only)模式。在此模式下,CSP策略不是强制执行的,但是任何违规行为将会报告给一个指定的URI地址。报告模式首部可以用来在不实际部署策略的情况下测试该策略的未来修订版本。
报告模式首部如下:Content-Security-Policy-Report-Only
如果Content-Security-Policy-Report-Only 头部和 Content-Security-Policy 同时出现在一个响应中,两个策略均有效。在Content-Security-Policy 头部中指定的策略有强制性 ,而Content-Security-Policy-Report-Only中的策略仅产生报告而不具有强制性。
如果策略里包含一个有效的report-uri 指令,支持CSP的浏览器将始终对于每个企图违反你所建立的策略都发送违规报告。
5 开启(违反策略)报告
默认情况下,并不会发送违反策略报告。需要指定 report-uri 策略指令并提供至少一个用于提交报告的URI地址来开启发送报告。
Content-Security-Policy: default-src 'self'; report-uri http://reportcollector.example.com/collector.cgi
需要设置服务器能够接收报告,使其能够以恰当的方式存储并处理这些报告。
6 报告语法 & 报告样例
{
"csp-report": {
"document-uri": "http://example.com/signup.html", --发生违规的文档的URI
"referrer": "",--违规发生处的文档引用(地址)
"blocked-uri": "http://example.com/css/style.css",--被CSP阻止的资源URI。如果被阻止的URI来自不同的源而非文档URI,那么被阻止的资源URI会被删减,仅保留协议,主机和端口号。
"violated-directive": "style-src cdn.example.com", -- 违反的策略名称
"original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports" --在 Content-Security-Policy HTTP 头部中指明的原始策略
}
}