Zer0e's Blog

浅谈CSP内容安全策略

字数统计: 1.1k阅读时长: 4 min
2018/07/12 Share

前言

CSP策略全称为Content Security Policy,是以白名单的机制对网站加载或者执行的资源起作用。CSP通常以HTTP头信息或者meta元素定义,可以较好的防御dom xss。

实现

1.使用meta标签,直接在页面中定义csp

1
<meta http-equiv="content-security-policy" content="策略">

这种方式较为简单,但需要每个页面都添加,较为繁琐。

2.使用HTTP头定义CSP
Apache :

Add the following to your httpd.conf in your VirtualHost or in an .htaccess file:

Header set Content-Security-Policy “default-src ‘self’;”

Nginx :

In your server {} block add:

add_header Content-Security-Policy “default-src ‘self’;”

也可使用PHP设置http头:

1
2
<?php
header("Content-Security-Policy: default-src 'self'");

CSP的书写规则

举个例子

1
2
3
4
//限制所有外部资源,所有资源只能从当前域名加载
Content-Security-Policy: default-src 'self'
//也可以指定资源网站
Content-Security-Policy: default-src http://xxx.com

default-src是CSP指令,多个指令用分号分隔,指令值用空格分隔,如:

1
Content-Security-Policy: default-src http://xxx.com; script-src http://aaa.com http://bbb.com
1
2
3
4
5
6
7
8
9
10
11
12
//通过report-uri指令发送拦截报告到指定地址
Content-Security-Policy: default-src 'self'; report-uri /report-uri;
//报告通常为:
{
"csp-report": {
"document-uri": "http://example.com/signup.html",
"referrer": "",
"blocked-uri": "http://example.com/css/style.css",
"violated-directive": "style-src cdn.example.com",
"original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports"
}
}

常用的CSP指令

指令指令和指令值示例指令说明
default-src‘self’ cdn.example.com默认加载策略
script-src‘self’ js.example.com对 JavaScript 的加载策略。
style-src‘self’ css.example.com对样式的加载策略。
img-src‘self’ img.example.com对图片的加载策略。
connect-src‘self’对 Ajax、WebSocket 等请求的加载策略。不允许的情况下,浏览器会模拟一个状态为 400 的响应。
font-srcfont.cdn.example.com针对 WebFont 的加载策略。
object-src‘self’针对 、 或 等标签引入的 flash 等插件的加载策略。
media-srcmedia.cdn.example.com针对媒体引入的 HTML 多媒体的加载策略。
frame-src‘self’针对 frame 的加载策略。
report-uri/report-uri告诉浏览器如果请求的资源不被策略允许时,往哪个地址提交日志信息。 特别的:如果想让浏览器只汇报日志,不阻止任何内容,可以改用 Content-Security-Policy-Report-Only 头。
sandbox设置沙盒环境
child-src主要防御 <frame>,<iframe>
form-action主要防御 <form>
frame-ancestors主要防御 <frame>,<iframe>,<object>,<embed>,<applet>
plugin-types主要防御 <object>,<embed>,<applet>

CSP指令值

指令值指令和指令值示例指令值说明
*img-src *允许任何内容。
‘none’img-src ‘none’不允许任何内容。
‘self’img-src ‘self’允许来自相同来源的内容(相同的协议、域名和端口)。
data:img-src data:允许 data: 协议(如 base64 编码的图片)。
example.comimg-src img.example.com允许加载指定域名的资源。
*.example.comimg-src *.example.com允许加载 example.com 任何子域的资源。
‘unsafe-inline’script-src ‘unsafe-inline’允许加载 inline 资源(例如常见的 style 属性,onclick,inline js 和 inline css 等等)。
‘unsafe-eval’script-src ‘unsafe-eval’允许加载动态 js 代码,例如 eval()。

演示

定义CSP,图片资源只能从当前域名加载

1
2
3
4
<?php
header("Content-Security-Policy: img-src 'self'");
$a = $_GET['a'];
echo "$a";

输入<img src=1.jpeg >图片成功加载

输入<img src="https://zer0blog.oss-cn-hangzhou.aliyuncs.com/blog_image/csp/01.png" >图片加载被浏览器阻止,stasus显示为blocked:csp

总结

CSP策略虽然通过白名单限制了资源的加载,减少了XSS攻击,但也造成了:Eval及相关函数被禁用、内嵌的JavaScript代码将不会执行、只能通过白名单来加载远程脚本,并且需要浏览器支持CSP策略。如果使用CSP策略,开发者不得不使内嵌脚本和文档分离,但好在CSP使开发者减少了对XSS攻击的负担。
现在大多数浏览器都已支持CSP策略,大大减少了用户被广告骚扰和盗取cookie的风险。

参见

Content-Security-Policy

CATALOG
  1. 1. 前言
  2. 2. 实现
  3. 3. CSP的书写规则
  4. 4. 常用的CSP指令
  5. 5. CSP指令值
  6. 6. 演示
  7. 7. 总结
  8. 8. 参见