Content-Security-Policy的实战应用

今天在浏览微信页面的时候,发现他的script标签上都有个once属性,好奇之下查阅了一番,发现这个属性是和一个http header Content-Security-Policy有关,这个header不看不知道,一看吓一跳啊,一把利器啊

1. 同源限制

首先我们要知道web浏览器为了安全都有会同源限制,什么是同源限制?就是来自 https://mybank.com 的代码应仅能访问 https://mybank.com 的数据,而绝不被允许访问 https://evil.example.com。同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据,比如cookie/locaStoragy/IndexDB就遵守同源限制。XMLHettpRequest也是存在同源限制,相信只要开发过web的同学在ajax获取数据时都遇到过这个问题。

同源限制可以一定程度上限制我们的用户信息不会被盗取,但是却没法防止我们的页面被插入不法分子的资源(js,img,css等),毕竟页面上带src的元素资源是不受同源限制的。这些页面上的牛皮鲜让人很讨厌,影响是极其恶劣的:会让我们的js监控误报、会影响用户体验、甚至隐私泄露,所以我们需要对src资源也作出一定的限制,这就得Content-Security-Policy来了

2. Content-Security-Policy(内容安全政策,下文简称为CSP)

  • 主要作用

了解一样东西,我们首先的知道他有啥用,没用不是浪费时间么,毕竟大家都在假装生活很忙的样子,作用呢主要有两点:

  1. 使用白名单的方式告诉客户端(浏览器)允许加载和不允许加载的资源。
  2. 向服务器举报这种强贴牛皮鲜广告的行为,以便做出更加针对性的措施予以绝杀。
  • 怎么用

我们知道了好处还是很犀利的啊,这么好的东西怎么玩?其实也很简单,前面说到了他其实就是一个http header嘛,所以我们只需要在返回html页面的同时加上个response header 就行了,后面的script-src代表是一个指令,指示浏览器你只能加载我屁股后面那些规则下的js代码,其他的都一律拒绝。

Content-Security-Policy: script-src 'self' https://apis.google.com

你还可以通过元标记的方式使用:

<meta http-equiv="Content-Security-Policy" content="default-src https://cdn.example.net; child-src 'none'; object-src 'none'">
  • 指令

前面说到script-src是一个指令,那就说明还有其他的指令罗,没有错,下面的都是指令,覆盖了web页面的所有资源

base-uri: 用于限制可在页面的 <base> 元素中显示的网址。
child-src: 用于列出适用于工作线程和嵌入的帧内容的网址。例如:child-src https://youtube.com 将启用来自 YouTube(而非其他来源)的嵌入视频。 使用此指令替代已弃用的 frame-src 指令。
connect-src: 用于限制可(通过 XHR、WebSockets 和 EventSource)连接的来源。
font-src: 用于指定可提供网页字体的来源。Google 的网页字体可通过 font-src https://themes.googleusercontent.com 启用。
form-action: 用于列出可从 <form> 标记提交的有效端点。
frame-ancestors: 用于指定可嵌入当前页面的来源。此指令适用于 <frame>、<iframe>、<embed> 和 <applet> 标记。此指令不能在 <meta> 标记中使用,并仅适用于非 HTML 资源。
frame-src: 已弃用。请改用 child-src。
img-src: 用于定义可从中加载图像的来源。
media-src: 用于限制允许传输视频和音频的来源。
object-src: 可对 Flash 和其他插件进行控制。
plugin-types: 用于限制页面可以调用的插件种类。
report-uri: 用于指定在违反内容安全政策时浏览器向其发送报告的网址。此指令不能用于 <meta> 标记,这就是举报电话
style-src: 是 script-src 版的样式表。
upgrade-insecure-requests: 指示 User Agent 将 HTTP 更改为 HTTPS,重写网址架构。 该指令适用于具有大量旧网址(需要重写)的网站。

这么多指令都要写?写起来不是很麻烦,不是的。你只需要写自己要求限制的指令就行,没写的都会默认没有限制。

你还可以通过指定一个 default-src 指令替换大部分指令的默认行为,也就说如果你写了default-src 指令,那其他没写的指令都会服从default-src 的规则。

  • 规则

规则主要是罗列一些你信任的域名,除此之外还有四个关键词:

none 表示不执行任何匹配。
self'表示与当前来源(而不是其子域)匹配。
unsafe-inline表示允许使用内联 JavaScript 和 CSS。
unsafe-eval 表示允许使用类似 eval 的 text-to-JavaScript 机制。

  • nonce属性

讲了这么多那和我一开始发现的那个script标签上的nonce属性有啥关系呢?首先说明不存在不正当*关系。主要是现代浏览器认为内联css和内联js都是应该被视为危险的行为,但是你总不能因为菜刀能杀人就不让百姓用菜刀了吧,所以开个口子吧。如果你在使用CSP策略的同时有确实需要使用内联css和js怎么办?用nonce+随机数的方式

<script nonce=EDNnf03nceIOfn39fn3e9h3sdfa>
  //Some inline code I cant remove yet, but need to asap.
</script>

然后我们在CSP的白名单中加上

Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

这样你这段内联js就可以生效了

补充说明

CSP 1 在 Chrome、Safari 和 Firefox 中非常实用,但在 IE 10 中仅得到非常有限的支持。 您可以 在 canisue.com 上查看具体信息。CSP Level 2 在 Chrome 40 及更高版本中可用。 Twitter 和 Facebook 等大量网站已部署此标头(Twitter 的案例研究值得一读),并为您开始在自己的网站上进行部署制定了相应标准。

实战效果

我们加上CSP头部后,开启csp上报功能后发现,10分钟上报了几千条,这被强奸的厉害啊,所以加上这个头部就显得更加有必要了

遇到的坑

在应用CSP后,有用户反映访问我们的站点出现问题,我们发现用户获取到的meta头乱了,而且在里面发现了一个不是我们写的域名:local.adguard.com,一查发现adguard是款 vpn软件,他对我们meta头部进行修改,修改就算了,还修改错了。后面我们改成response header的方式,不使用meta了,发现他也会修改http的response header,但是没修改错,垃圾VPN害死人啊

今天发现有个CDN劫持相关的议题也挺有意思的

具体内容可以看这篇知乎回答,里面提到一个关键词SRI

参考文章:

同源限制 - 阮一峰
内容安全政策 - Google

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 前端开发面试知识点大纲: HTML&CSS: 对Web标准的理解、浏览器内核差异、兼容性、hack、CSS基本功:...
    秀才JaneBook阅读 2,313评论 0 25
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,490评论 18 139
  • AJAX 原生js操作ajax 1.创建XMLHttpRequest对象 var xhr = new XMLHtt...
    碧玉含香阅读 3,146评论 0 7
  • 本文旨在加深对前端知识点的理解,资料来源于网络 position的值, relative和absolute分别是相...
    新晋小牛牛阅读 1,324评论 0 15
  • 我离老师给出的主题似乎越来越远,我只写我能想到的东西。 拿到这本书,感觉就像手里拿着一盏灯了,在前进的路上可以看清...
    by_10阅读 265评论 0 0