概述
内容安全策略(CSP),其核心思想十分简单:网站通过发送一个 CSP 头部,来告诉浏览器什么是被授权执行的与什么是需要被禁止的。其被誉为专门为解决XSS攻击而生的神器。
前言
内容安全策略 (CSP) 是一个额外的安全层,用于检测并削弱某些特定类型的攻击,包括跨站脚本 (XSS) 和数据注入攻击等。无论是数据盗取、网站内容污染还是散发恶意软件,这些攻击都是主要的手段。
CSP 的实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置。
CSP 大大增强了网页的安全性。攻击者即使发现了漏洞,也没法注入脚本,除非还控制了一台列入了白名单的可信主机。
CSP作用
- 限制资源获取
- 报告资源获取越权
应对威胁
1 跨站脚本攻击
CSP 的主要目标是减少和报告 XSS 攻击 ,XSS 攻击利用了浏览器对于从服务器所获取的内容的信任。恶意脚本在受害者的浏览器中得以运行,因为浏览器信任其内容来源,即使有的时候这些脚本并非来自于它本该来的地方。
CSP通过指定有效域——即浏览器认可的可执行脚本的有效来源——使服务器管理者有能力减少或消除XSS攻击所依赖的载体。一个CSP兼容的浏览器将会仅执行从白名单域获取到的脚本文件,忽略所有的其他脚本 (包括内联脚本和HTML的事件处理属性)。
作为一种终极防护形式,始终不允许执行脚本的站点可以选择全面禁止脚本执行。
2 数据包嗅探攻击
除限制可以加载内容的域,服务器还可指明哪种协议允许使用;比如 (从理想化的安全角度来说),服务器可指定所有内容必须通过HTTPS加载。一个完整的数据安全传输策略不仅强制使用HTTPS进行数据传输,也为所有的cookie标记安全标识 cookies with the secure flag,并且提供自动的重定向使得HTTP页面导向HTTPS版本。网站也可以使用 Strict-Transport-Security HTTP头部确保连接它的浏览器只使用加密通道。
CSP使用
CSP分类:
-
限制资源获取:Content-Security-Policy
配置好并启用后,不符合 CSP 的外部资源就会被阻止加载。 -
报告资源获取越权:Content-Security-Policy-Report-Only
表示不执行限制选项,只是记录违反限制的行为。它必须与report-uri选项配合使用。
启用 CSP
- 通过 HTTP 头信息的
Content-Security-Policy
的字段(推荐)
// header头配置
Content-Security-Policy: script-src 'self'; object-src 'none';
style-src cdn.example.org third-party.org; child-src https:
`<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:">
指令说明
以下是常用的指令说明:
指令名 | demo | 说明 |
---|---|---|
default-src | 'self' cdn.example.com | 默认策略,可以应用于js文件/图片/css/ajax请求等所有访问 |
script-src | 'self' js.example.com | 定义js文件的过滤策略 |
style-src | 'self' css.example.com | 定义css文件的过滤策略 |
img-src | 'self' img.example.com | 定义图片文件的过滤策略 |
connect-src | 'self' | 定义请求连接文件的过滤策略 |
font-src | font.example.com | 定义字体文件的过滤策略 |
object-src | 'self' | 定义页面插件的过滤策略,如 , 或者等元素 |
media-src | media.example.com | 定义媒体的过滤策略,如 HTML6的 , 等元素 |
frame-src | 'self' | 定义加载子frmae的策略 |
sandbox | allow-forms allow-scripts | 沙盒模式,会阻止页面弹窗/js执行等,你可以通过添加allow-forms allow-same-origin allow-scripts allow-popups, allow-modals, allow-orientation-lock, allow-pointer-lock, allow-presentation, allow-popups-to-escape-sandbox, and allow-top-navigation 策略来放开相应的操作 |
指令值
所有以-src结尾的指令都可以用一下的值来定义过滤规则,多个规则之间可以用空格来隔开
值 | demo | 说明 |
---|---|---|
* | img-src * | 允许任意地址的url,但是不包括 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' | 允许行内代码执行 |
'unsafe-eval' | script-src 'unsafe-eval' | 允许不安全的动态代码执行,比如 JavaScript的 eval()方法 |
验证
可以通过检查headers信息中的Content-Security-Policy字段
浏览器拦截现象
启用后,不符合 CSP 的外部资源就会被阻止加载。
- Chrome 的报错信息
- Firefox 的报错信息
配置示例
示例:禁用不安全的内联/动态执行,只允许通过 https 加载这些资源(如图片、字体、脚本等):
// header
Content-Security-Policy: default-src https:
// meta tag
<meta http-equiv="Content-Security-Policy" content="default-src https:">
示例:已经存在的一个网站,用了太多内联代码修复问题,而且想确保资源只从 https 加载,并且禁止插件:
Content-Security-Policy: default-src https: 'unsafe-eval' 'unsafe-inline'; object-src 'none'
注:具体配置需要结合项目情况配合上述指令说明进行配置
如:我使用的是Lighttpd服务器,用了很多内联代码,需要确保资源只从https加载,禁止插件,同时使用了websocket,可以进行一下配置
setenv.add-response-header += ( "Content-Security-Policy" => "default-src https: 'unsafe-inline'; object-src 'none';connect-src https: wss:")
最后附上其他服务推荐配置以及参考
- apache
Header set Content-Security-Policy "script-src 'self'; object-src 'self'"
- nginx
add_header Content-Security-Policy "script-src 'self'; object-src 'self'";
-
对于 Apache 请参阅: httpd.apache.org/docs/2.2/mo…
-
对于 IIS,请参阅: technet.microsoft.com/pl-pl/libra…
-
对于 nginx,请参阅: nginx.org/en/docs/htt…