网页安全政策

网页安全政策是什么

"网页安全政策"(Content Security Policy,缩写 CSP),本质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置。

就是因为有了CSP的存在,大大增加了网页的安全性,网络攻击者就算发现了漏洞也没有办法注入脚本,除非控制了一台或多台信任的站点或者主机。

怎么使用CSP

1. HTTP头信息

通过在设置HTTP头信息的网页安全政策的字段进行声明“Content-Security-Policy”字段

Content-Security-Policy: script-src 'self'; object-src 'none';
style-src cdn.example.org third-party.org; child-src https:

2.<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:">

不管使用哪个方式,以上的内容一共就是做了如下几件事情:

  1. 脚本:只信任当前域名
  2. <object>标签:不信任任何URL,即不加载任何资源
  3. 样式表:只信任cdn.example.org和third-party.org
  4. 框架(frame):必须使用HTTPS协议加载
  5. 其他资源:没有限制

只要启用 CSP ,不符合 规则的外部资源就会被阻止加载。

限制选项

CSP 提供了很多限制选项,涉及安全的各个方面

  • default-src : 定义针对所有类型(js/image/css/font/ajax/iframe/多媒体等)资源的默认加载策略,如果某类型资源没有单独定义策略,就使用默认的。
  • script-src : 定义针对 JavaScript 的加载策略。
  • style-src : 定义针对样式的加载策略。
  • img-src : 定义针对图片的加载策略。
  • font-src : 定义针对字体的加载策略。
  • media-src : 定义针对多媒体的加载策略,例如:音频标签<audio>和视频标签<video>。
  • object-src : 定义针对插件的加载策略,例如:<object>、<embed>、<applet>。
  • child-src :定义针对框架的加载策略,例如: <frame>,<iframe>。
  • connect-src : 定义针对 Ajax/WebSocket 等请求的加载策略。不允许的情况下,浏览器会模拟一个状态为400的响应。
  • sandbox : 定义针对 sandbox 的限制,相当于 <iframe>的sandbox属性。
  • report-uri : 告诉浏览器如果请求的资源不被策略允许时,往哪个地址提交日志信息。
  • form-action : 定义针对提交的 form 到特定来源的加载策略。
  • referrer : 定义针对 referrer 的加载策略。
  • reflected-xss : 定义针对 XSS 过滤器使用策略。

限制选项值

  • *允许加载任何内容
  • ‘none‘ 不允许加载任何内容
  • ‘self‘ 允许加载相同源的内容
  • www.a.com 允许加载指定域名的资源
  • *.a.com 允许加载 a.com 任何子域名的资源
  • https://a.com 允许加载 a.com 的 https 资源
  • https: 允许加载 https 资源
  • data: 允许加载 data: 协议,例如:base64编码的图片
  • ‘unsafe-inline‘ 允许加载 inline 资源,例如style属性、onclick、inline js、inline css等
  • ‘unsafe-eval‘ 允许加载动态 js 代码,例如 eval()

CSP 默认特性

  • 阻止内联代码执行

CSP除了使用白名单机制外,默认配置下阻止内联代码执行是防止内容注入的最大安全保障。
这里的内联代码包括:<script>块内容,内联事件,内联样式。

  1. script代码,<script>……<scritp>,对于<script>块内容是完全不能执行的
  2. 内联事件
  3. 内联样式

虽然CSP中已经对script-src和style-src提供了使用”unsafe-inline”指令来开启执行内联代码,但为了安全起见还是慎用”unsafe-inline”。

  • EVAL相关功能被禁用
    用户输入字符串,然后经过eval()等函数转义进而被当作脚本去执行。这样的攻击方式比较常见。于是乎CSP默认配置下,eval() , newFunction() , setTimeout([string], …) 和setInterval([string], …)都被禁止运行。
    比如:
alert(eval("foo.bar.baz"));
window.setTimeout("alert(‘hi‘)", 10); window.setInterval("alert(‘hi‘)", 10); 
new Function("return foo.bar.baz");

如果想执行可以把字符串转换为内联函数去执行。

alert(foo && foo.bar && foo.bar.baz);
window.setTimeout(function() { alert(‘hi‘); }, 10);
window.setInterval(function() { alert(‘hi‘); }, 10);
function() { return foo && foo.bar && foo.bar.baz };

同样CSP也提供了”unsafe-eval”去开启执行eval()等函数,但强烈不建议去使用”unsafe-eval”这个指令。

CSP 记录报告

可以用report-uri指令使浏览器发送HTTP POST请求把攻击报告以JSON格式传送到你指定的地址。
开启步骤:
1. 启用报告
默认情况下,违规报告不会发送。为了能使用违规报告,你必须使用report-uri指令,并至少提供一个接收地址。

Content-Security-Policy: default-src self; report-uri http://reportcollector.example.com/collector.cgi

如果想让浏览器只汇报报告,不阻止任何内容,可以改用Content-Security-Policy-Report-Only头

2. 违规报告语法
该报告JSON对象包含以下数据:

blocked-uri:被阻止的违规资源
document-uri:拦截违规行为发生的页面
original-policy:Content-Security-Policy头策略的所有内容
referrer:页面的referrer
status-code:HTTP响应状态
violated-directive:违规的指令

违规报告例子

http://example.com/signup.html 中CSP 规定只能加载cdn.example.com的CSS样式。

Content-Security-Policy: default-src ‘none‘; style-src cdn.example.com; report-uri /test/csp-report.php

signup.html中的代码类似与这样:

<!DOCTYPE html>
<html>
 <head>
   <title>Sign Up</title>
   <link rel="stylesheet" href="css/style.css">
 </head>
 <body>
   ... Content ...
 </body>
</html>

以上代码触犯了页面想自行加载自己域中的样式表,所以浏览器就会向 预设好的网址 http://example.com/test/csp-report.php 发送报告,发送格式为:

{
  "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",
  }
}

从上面可以看到blocked-uri给出了详细的阻断地址 http://example.com/css/style.css,但也并不是每次都是这样。比如试图从 http://anothercdn.example.com/stylesheet.css 加载CSS样式时,浏览器将不会传送完整的路径,只会给出 http://anothercdn.example.com/ 这个地址。这样做是为了防止泄漏跨域的敏感信息。

参考链接

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 01 XSS攻击与防御 一、Cookie 定义 Cookie是指某些网站为了辨别用户身份而存储在客户端上的数据(通...
    Ackerzy阅读 2,724评论 3 10
  • 一. 浏览器安全策略 同源策略 浏览器的安全都是以同源为基础,它是浏览器最核心也最基本的安全功能 同源策略规定:不...
    菊花泡茶阅读 546评论 0 0
  • https://www.html5rocks.com/en/tutorials/security/content-...
    谢大见阅读 5,721评论 0 3
  • 前言 Web安全问题一直是前端领域一个绕不开的话题,但很多前端人员对Web的相关安全策略都只停留在面试过程中,本文...
    维李设论阅读 636评论 0 0
  • 使用以下HTTP头部可帮你快速容易地预防XSS攻击、点击挟持攻击、MIME嗅探和中间人攻击。如果目前还没使用,通过...
    牧童US阅读 1,662评论 0 0