背景
互联网的超速发展,信息安全问题已经成为企业的核心关注焦点之一,用户体验的极大提升也为前端的安全带来了很大的挑战,前端安全也是企业安全问题的高危点。在移动互联网时代,前端人员经常直面XSS、CSRF、网络劫持等网络攻击手段,即便现代浏览器不断的优化发展,引入一系列的新技术来增强安全性,但是潜在的风险迫使前端不断进行“查漏补缺”。本文将着重介绍一个防范XSS攻击的神器-内容安全策略(CSP)。内容安全策略-CSP
内容安全策略 (CSP, Content Security Policy) 是一个附加的安全层,用于帮助检测和缓解某些类型的攻击,包括跨站脚本 (XSS) 和数据注入等攻击。这些攻击可用于实现从数据窃取到网站破坏或作为恶意软件分发版本等用途。 CSP的主要目的是减少和报告XSS攻击,其实质就是一个“白名单”,开发者用其告诉客户端哪些资源(通常包括脚本,图片,iframe,style,font等可能的远程资源和内联脚本等)可以加载和执行,开发者只需要提供配置,然后交给浏览器去完成执行。 CSP可以大大的增强网页的安全性,降低内容注入漏洞的风险,并降低其应用程序的执行权限。目前的主流浏览器都已支持CSP,所以可以放心大胆的使用。CSP的启用
CSP的启用方式有两种: 1、通过HTTP头信息Header的 Content-Security-Policy 字段配置Content-Security-Policy: ;
2、通过网页HTML的 标签配置
两种方法只是配置方式不同,其作用是一致的,如果HTTP请求头与标签同时存在,则优先采用HTTP请求头中的配置。
CSP的使用实例
以下的举例以HTTP请求头配置为例,配置中多个指令之间用英文分号分割,多个指令值用英文空格分割。// 限制所有外部资源,只允许加载当前域名的资源Content-Security-Policy: default-src 'self'// 已经存在的一个网站,用了太多内联代码修复问题,而且想确保资源只从 https 加载,并且禁止插件:Content-Security-Policy: default-src https: 'unsafe-eval' 'unsafe-inline'; object-src 'none'// 允许网页加载来自任何源的图片, 但是限制音频或视频需从指定的域名获取,所有脚本须从指定域名获取Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src scripts.example.com
CSP的指令
常用的指令如下:
指令 | 指令说明 |
default-src | 默认策略,为其他取指令提供备用服务 |
script-src | JS的加载策略,限制JavaScript的源地址 |
img-src | 图片加载策略,限制图片和图标的源地址 |
style-src | 样式的加载策略,限制样式表文件源 |
connect-src | 对Ajax,WebSocket等请求的加载策略,限制能通过脚本接口加载的URL,不允许的情况下浏览器会模拟一个状态为400的响应 |
font-src | 针对WebFont的加载策略,设置允许通过@font-face加载的字体源地址 |
object-src | 限制、、标签的源地址 |
media-src | 针对HTML引入的多媒体的加载策略,限制通过、 |
frame-src | 针对frame的加载策略,设置允许通过类似和 |
report-uri | 当出现违反CSP的操作时,让客户端提交报告。这些违规报告会以JSON文件的格式通过POST请求发送到指定的URI |
worker-src | 限制Worker、SharedWorker或者ServiceWorker脚本源。 |
其他CSP指令
指令 | 指令说明 |
sandbox | 设置沙盒模式,类似 |
child-src | 防御 |
form-action | 防御,限制 form 的 action 属性的链接地址 |
frame-ancestors | 指定可能嵌入页面的有效父项, |
plugin-types | 主要防御、、,通过限制可以加载的资源类型来限制哪些插件可以被嵌入到文档中。 |
CSP的指令值
指令值 | 指令值说明 |
* | 允许任何内容 |
'none' | 不允许任何内容 |
'self' | 允许来自相同来源的内容(相同的协议、域名和端口) |
data: | 允许data:协议,如base64的图片或字体 |
www.xing666.net | 允许加载指定域名的资源 |
*.xing666.net | 允许加载任何xing666.net子域名的资源 |
'unsafe-inline' | 允许加载inline资源(如 |
'unsafe-eval' | 允许加载动态js代码,如 eval() |
https: | 只允许通过 https 协议加载资源 |
CSP的报告模式
为降低部署成本,CSP可以部署为报告(report-only)模式。在此模式下,CSP策略不是强制性的,但是任何违规行为将会报告给一个指定的URI地址。此外,一个报告模式的头部可以用来测试一个修订后的未来将应用的策略而不用实际部署它。
配置如下:
Content-Security-Policy-Report-Only: policy
Content-Security-Policy: default-src 'self'; report-uri http://xing666.net/report
如果Content-Security-Policy-Report-Only 头部和 Content-Security-Policy 同时出现在一个响应中,两个策略均有效。在Content-Security-Policy 头部中指定的策略有强制性 ,而Content-Security-Policy-Report-Only中的策略仅产生报告而不具有强制性。
支持CSP的浏览器将始终对于每个企图违反你所建立的策略都发送违规报告,违规报告发送到有效的report-uri 指令。
报告样例:
{
"csp-report": {
"document-uri": "http://www.xing666.net/example.html",
"referrer": "",
"blocked-uri": "http://a.baidu.com/css/style.css",
"violated-directive": "style-src cdn.xing666.net",
"original-policy": "default-src 'none'; style-src cdn.xing666.net; report-uri http://www.xing666.net/report"
}
}
CSP的使用注意点
1、为了使用策略生效,应该将 Meta 元素头放在开始位置,以防止提高人为的 CSP 策略注入。
2、script-src 和 object-src 是必设的,除非设置了 default-src。因为攻击者只要能注入脚本,其他限制都可以规避。而 object-src 必设是因为 Flash 里面可以执行外部脚本。