# 背景
- 跨站脚本攻击XSS是最常见、危害最大的网页安全漏洞
- 为了从根本上解决问题,浏览器自动禁止外部注入恶意脚本
# 简介
- 本质是白名单制度
- 大大增强了网页的安全性
# 生效方式
Http响应头
信息的 Content-Security-Policy字段网页
的**标签**
# 配置规则
# 配置项(主要)
配置项名称 | 作用 |
---|---|
script-src | 外部脚本 |
style-src | 样式表 |
img-src | 图像 |
media-src | 媒体文件(音频和视频) |
font-src | 字体文件 |
object-src | 插件(如 Flash) |
child-src | 框架 |
frame-ancestors | 可被嵌入的外部网页(如frame,iframe,embed,applet) |
connect-src | http连接(如XHR,WebSocket等) |
# 默认配置项
- default-src,用于配置内容安全策略各选项的默认值.
- 同时配置了单项限制,将会覆盖默认值。
# 其它限制
- block-all-mixed-content: Https网页不得加载http资源(浏览器已经默认开启)
# 配置项的值类型
值类型 | 值示例 |
---|---|
主机名 | example.org,https://example.com:443 |
路径名 | example.org/resources/js |
通配符 | *.example.org, *😕/*.example.com:*(表任意协议,任意子域名,任意端口) |
协议名 | https:,data: |
关键字'self' | ’selft‘, 当前域名,需要加引号 |
关键字'none' | 'none', 禁止加载任何外部资源,需要加引号 |
- 多个值可以并列,用空格分隔
- 同一个限制选项使用多次,只有第一次会生效,如
script-src https://host1.com; script-src https://host2.com
,host1生效
# script-src的特殊值
特殊值 | 特殊值含义 |
---|---|
'unsafe-inline' | 允许执行页面内嵌的<script> 标签和事件监听函数 |
’unsafe-eval‘ | 允许将字符串当作代码执行,如使用eval,setTimeout,setInterval和Function等 |
nonce值 | 每次http响应给出一个授权token,页面内嵌脚本必须有这个token,才会执行 |
hash值 | 流出允许执行的脚本代码的hash值,页面内嵌脚本的hash值,只有温和的情况下,才能执行 |
# 注意事项
- script-src和 object-src是必设的,除非设置了
default-src
- script-src不建议使用
unsafe-inline
关键字(除非伴随一个nonce值),也不建议设置data:
;<img src="x" onerror="evil()"> <script src="data:text/javascript,evil()"></script>
# 兼容性
- 在老版本浏览器不支持
CSP
之前,可支持X-Frame-Option
增加安全性 - 支持
CSP
的浏览器,则不再支持X-Frame-Option
# 实践
- 配置放行类似于 “黑名单规则”,即不限制即放行;
# 实例说明
<filter>
<filter-name>FrontEndResourceCSPFilter</filter-name>
<filter-class>xxx.xxx.xxx.common.FrontEndResourceCSPFilter</filter-class>
<init-param>
<param-name>cspPolicy</param-name>
<param-value>default-src 'self' 'unsafe-inline' 'unsafe-eval' 'self' 172.20.20.52:* 172.20.20.119:* *.baidu.com wss: data: ws: ; frame-ancestors 'self';</param-value>
</init-param>
</filter>
- 该例允许 所有的 ws协议,data协议,wss协议连接(未指定具体地址); 允许主机 172.20.20.52, 172.20.20.19的所有连接(未指定协议及端口,此处协议特指http以及https), 允许域名baidu.com及其子域名的所有连接(通配);
- 如果不限制端口,需要使用通配进行指定(https默认443端口,http默认80端口);
- http或者https协议,不需要使用通配进行指定;