CloudFlare旨在终结未加密的互联网。但我们在网络上一谈论到HTTPS就会面临一个先有鸡还是先有蛋的问题。
很久以前,建立支持HTTPS的网站很困难,昂贵且速度慢。后来出现了像CloudFlare的Universal SSL这样的服务,它使得从http://切换到https://就像点击按钮一样简单。只需点击一下网址,就可以通过HTTPS提供一个新建的免费SSL证书。
Boom
一下子,该网站可以通过HTTPS,更好的是,网站变得更快了,因为它可以使用最新的Web协议HTTP / 2。
不幸的是,故事并没有就此结束。许多其他安全站点都存在混合内容的问题。混合内容意味着https://网站不会显示绿色挂锁图标,因为它并不是真正安全的。
问题在于:如果https://网站包含来自http://网站(甚至是自己的)提供的任何内容,则绿色挂锁无法显示。这是因为http://上包含的图像,JavaScript,音频,视频等资源成为了安全网站的安全漏洞。它们将带来故障。
Web浏览器很久前就已经意识到这一问题。早在1997年,Internet Explorer 3.0.2就已通过以下对话框警告用户这些具有混合内容的网站。
现在,谷歌浏览器会在任何具有不安全内容的https://上显示带圆圈的i。
Firefox对此会显示带有警告符号的挂锁。若要从这些浏览器中获取绿色挂锁,则每个子资源(页面加载的资源)都需要通过HTTPS提供。
在1997年,如果你点击了Yes,那么Internet Explorer就会忽略混合内容的不安全性,并继续使用明文HTTP加载子资源。单击“否”会阻止加载它们(这通常会导致网页损坏,但确保了网页安全)。
过渡到完全安全的内容
你可能会以为混合内容的问题很容易解决:“只需使用https://加载所有内容,然后就能修复您的网站。” 这种想法很诱人,但是很天真。然而,从第一方和第三方网站加载到现代网站的内容大杂烩使得这种改变很难“简单”实现。
Wired 在一系列博客中记录了他们向https://的过渡,体现了将所有内容切换到HTTPS的难度。从四月份开始,他们在这个过程中花了5个月的时间(在几个月前就已经做好准备,只为了在他们的主网站上看到https://)。在五月,他们记录了一个阻碍:
“[...]转移到HTTPS的最大挑战之一就是准备通过安全连接提供所有内容。要通过HTTPS加载页面,还必须通过HTTPS加载所有其他资源(如图像和Javascript文件)我们看到大量关于这些“混合内容”问题的报告,或者在安全的HTTPS页面上加载不安全的HTTP资源的事件。为了正确上线网站,我们需要确保混合内容问题较少——因此我们要尽可能安全地提供WIRED.com的内容。”
2014年,“纽约时报”将混合内容视为安全的主要障碍:
“要成功转移到HTTPS,所有对页面资源的请求都需要通过安全通道进行。这是一项艰巨的挑战,而且其中还有很多活动部分。我们必须考虑当前从不安全域加载的资源——一切从JavaScript到广告资源的内容。”
W3C 认为这是一个很大的问题:_“最值得注意的是,混合内容检查有可能给负责将大量遗留内容迁移到HTTPS的管理员带来真正的麻烦。而且,浏览旧内容并手动重写资源URL是一项艰巨的任务。”_W3C还引用了BBC的庞大存档作为一个困难案例。
但并不是只有媒体网站存在混合内容的问题。许多CMS用户发现更新CMS生成的所有链接是很难或不可能的,因为它们可能隐藏在配置文件,源代码或数据库中。此外,需要处理用户生成内容的网站也面临http:// URIs的问题。
混合内容的危害
混合内容有两种形式:主动和被动。现代Web浏览器可以通过如下方式解决这些不同类型的混合内容的危险:完全隔绝主动混合内容(最危险的部分),允许被动混合内容通过,但浏览器会发出警告。
主动内容可以修改DOM(网页本身)的任何内容。包括通过 <script>
, <link>
, <iframe>
或 <object>
标签还有CSS值来调用 url
,以及任何要求使用 XMLHTTPRequest
的资源,都能够修改一个页面,浏览cookies和访问用户的信任凭证。
被动内容就是其他内容:图像,音频,视频,他们被写入页面但不能自己访问页面。
主动内容是一个真正的威胁,因为如果攻击者设法拦截对http:// URI的请求,他们可以用自己的内容替换该内容。这并非纸上谈兵。2015年,Github受到一个名为Great Cannon的系统的攻击,该系统通过HTTP拦截了对常见JavaScript文件的请求,并用JavaScript攻击脚本替换了它们。Great Cannon通过拦截TCP并利用从http:// URIs加载的主动内容中的固有漏洞来武装无辜用户的机器。
被动内容是一种不同的威胁:因为被动内容的请求是明文发送的,窃听者可以监视请求并提取信息。例如,定位良好的窃听者可以监控cookie,访问过的网页以及潜在的身份验证信息。
Firesheep Firefox插件就可以用来监控本地网络(例如,在咖啡店)发送的HTTP请求,并自动窃取cookie,这允许用户通过一个点击就能劫持某个人的身份。
如今,现代浏览器阻止了不安全加载的主动内容,但允许被动内容通过。然而,过渡到完全的https://才是解决混合内容的所有安全问题的唯一方法。
自动修复混合内容
我们希望长期帮助修复混合内容,因为我们的目标是网络完全加密。而且,与其他CloudFlare服务一样,我们希望其能带来 “一键式”体验。
我们考虑了很多方法:
自动插入upgrade-insecure-requests CSP指令
该upgrade-insecure-requests 指令可以在添加内容安全政策的题头,如下:
Content-Security-Policy: upgrade-insecure-requests
它指示浏览器自动将任何HTTP请求升级到HTTPS。如果网站所有者确定每个子资源都可通过HTTPS获得,则此功能非常有用。该网站不必实际将网站中嵌入的http:// URI更改为https://,浏览器将自动处理该问题。
不幸的是,upgrade-insecure-requests存在很大的缺点。由于浏览器会盲目地将每个URI升级到https://,不管生成的URI是否真正起作用,因此页面会被破坏。
将所有链接改为使用https://
由于并非所有访问CloudFlare网站的用户使用的浏览器都支持upgrade-insecure-requests,因此我们考虑当网页通过我们的服务时,将所有http:// URI升级到https://。由于我们能够实时解析和修改网页,因此我们可以创建一个无需浏览器支持的“upgrade-insecure-requests”服务。
不幸的是,当http:// URI转换为https://但是实际上无法使用HTTPS加载资源时,用户仍会遇到链接断开的问题。
修改指向其他CloudFlare站点的链接
由于CloudFlare为我们所有的400万客户提供免费的通用SSL,覆盖了很大比例的网络流量,我们认为只需将我们知道的(因为他们使用我们的服务)http://的URI升级到支持https://就可以起作用。
这解决了部分问题,但对于从HTTP升级到HTTPS的一般问题,这不是一个好的解决方案
创建一个可重写已知且支持HTTPS的URI的系统
最后,我们决定做一些明智的事情:如果我们知道可以使用HTTPS上传资源,则将URI从http://升级到https://。为了弄清楚哪些链接可以升级,我们求助了EFF优秀的HTTPS Everywhere扩展和Google Chrome HSTS预加载列表,这增强了我们对启用了SSL的CloudFlare站点的了解。
我们非常感谢EFF慷慨地答应了帮助我们完成这个项目。
HTTPS Everywhere规则集不仅仅是将http://切换到https://:它还包括一些允许它(和我们)将一些特定uri视为目标地址的规则(和排除规则)。
<rule from="^http://(csi|encrypted-tbn\d|fonts|g0|[\w-]+\.metric|ssl|t\d)\.
gstatic\.com/" to="https://$1.gstatic.com/"/>
以下是一个真实的gstatic.com的HTTP Everywhere规则:
它使用正则表达式来标识gstatic.com的特定子域,可以安全地升级为使用HTTPS。点击此处可浏览完整的规则集。
因为我们需要升级嵌入在网页中的大量URI(我们估计大约每秒500万),我们对现有的HTML解析器(包括我们自己的)进行了基准测试,并决定为这种类型的重写任务编写一个新的解析器。我们将在以后的文章中详细介绍其设计,测试和性能。
自动HTTPS重写
现在,所有CloudFlare用户的用户面板中都提供了自动HTTPS重写功能。现在,此功能在默认情况下禁用,可以“一键”启用:
我们将监控此功能的性能和有效性,并在今年晚些时候为Free和Pro客户默认启用该功能。我们还计划使用内容安全策略(Content Security Policy)报告功能,让客户自动查看哪些URI仍需要升级,以便尽可能简单地转换到https://,因为有时候仅仅找到需要更改的uri就非常困难了,正如Wired所发现的。
想知道这个功能对您有什么帮助吗?