CSP,全称Content Security Policy,意即内容安全策略,有非常多的指令,用来实现各种各样与页面内容安全相关的功能,这里介绍2个比较有用的。所有CSP指令都有2种启用方式,一种是HTTP头部,一种是<meta>标签。
4.1.1. 禁用http链接前面说过,对于HTTPS页面中的图片等资源浏览器默认会加载,仅仅是控制台给一个警告,因为图片类资源被劫持通常问题不会太大,但有些页面按钮布局等是用图片做的,图片被篡改会影响用户使用,最重要的,页面只要有一个http的链接,地址栏的https就不是绿色的。
可以通过CSP的block-all-mixed-content指令让页面进入对Mixed Content的严格检测(Strict Mixed Content Checking)模式。在这种模式下,所有非 HTTPS 资源都被禁止加载,控制台报错,https回归绿色。
HTTP响应头方式:
Content-Security-Policy: block-all-mixed-contentHTML标签方式:
<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">
4.1.2. 强制http指向httpsHTTP迁移HTTPS对于一些大型网站来说工作量巨大,难免有疏漏的地方,此时可以让浏览器帮我们做http自动跳转https这一步。通过upgrade-insecure-requests这个CSP指令,可以让浏览器帮忙做这个转换,启用这个策略后,不仅是http静态资源,http接口调用也会自动转成https再发出去。
这里只介绍HTML标签方式:
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
效果如下图,http的图片自动变成https:
4.2. HSTS:防止HTTPS降级劫持99%的人访问一个网站都不会主动输入http前缀,https就更是如此,因为用户又不知道你的网站是不是https的,所以几乎所有的https网站都是通过http的301/302自动跳转的方式来让用户进入。注意,由于第一次是http访问,如果第一次访问就被劫持那用户根本到不了https页面,这就叫https降级劫持。
这个问题可以通过HSTS(HTTP Strict Transport Security)来解决。HSTS是一个响应头,格式如下:
Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload]max-age,单位是秒,用来告诉浏览器在指定时间内这个网站必须通过 HTTPS 协议来访问,比如说我设置一年,那么一年以内即使用户输入http并且被劫持了,浏览器依然会以HTTPS的方式来访问;
includeSubDomains,可选参数,如果指定这个参数,表明这个网站所有子域名也必须通过 HTTPS 协议来访问。
preload,可选参数,是否启用preload list,关于这个是什么后面再介绍。
注意HSTS这个响应头是添加到HTTPS响应头中而不是HTTP响应的,这可能和我们预期的不一样,如果一个HTTPS网站从来没被访问过,那这个HSTS头永远生效不了,那怎么办呢?浏览器厂商们为了解决这个问题,提出了一个HSTS Preload List方案:内置一份可以定期更新的启用HSTS的域名列表,对于列表中的域名,即使用户之前没有访问过,也会使用 HTTPS 协议。看起来这个主意挺馊的,但这也是没办法的办法。想要加入这个列表需要很多强制要求,而且满足了也不一定能申请成功,我们这里就不细讲了。
另外,启用HSTS必须使用默认的 443 端口;必须使用域名,不能是 IP。而且启用 HSTS 之后,一旦网站证书错误,用户无法选择忽略。
建议:只要你不能确保永远提供 HTTPS 服务,就不要启用。因为一旦 HSTS 生效,你再想把网站重定向为 HTTP,之前的老用户会被无限重定向,唯一的办法是换新域名。
4.3. Fiddler抓包HTTPS默认情况下Fiddler不会对HTTPS网站抓包,要启用的话步骤如下:
Tool -> Fiddler Options:
然后在IE代理中启用对HTTPS的代理(默认仅开启了HTTP):
Fiddler会为每一个网站动态颁发一个*.xxx.com的证书,想要看网站真正证书时需关闭Fiddler: