HTTPS安全最佳实践

HTTPS对于保护你的网站至关重要。但是你还需要避免许多陷阱

1. 没有混合内容
混合内容是指在你的HTTPS站点中不能通过HTTP加载资源了。浏览器会清晰显示你的网站是否容易混合内容,在浏览器网址一栏有图标。

如果曾经将http://网址硬编码到你网站,之后你又将网站迁移到HTTPS时就会出现这种情况。

首先使用https://URL,或者只是将该方案保留并使用//,这指示浏览器使用与页面相同的方案,即http://HTTP和https://HTTPS。

2. 检查HTTPS配置
HTTPS是没有二进制状态,因此仅将其激活还是不够的,有许多配置选项会影响加密本身的各个方面。

幸运的是,有些网站会测试你的配置并提供如何解决某些问题的建议。其中之一是来自Qualys的SSL服务器测试,它运行一组强大的检查。

请务必不时查看你的HTTPS配置,因为可能会出现新的漏洞和最佳做法。

3. 检查HTTP标头
有几个HTTP标头header可以控制具有安全隐患的方面,虽然并非所有这些标头都与HTTPS相关。

这个网站能帮助检查安全头,它提供了一些很重要标头的说明。

4. 获得有关新证书​​的通知
添加最近颁发证书的过程就是所谓的证书透明度,这意味着无论何时为你的域名发布证书时,都必须将其提交给公共日志,实际上,你可以查看你域的所有证书。

甚至可以在发布新证书时订阅通知并收到电子邮件,同样,有几个这样的服务可用,例如,有一个来自Facebook

5. 如何处理HTTP
一个常见的误解是,如果除了重定向到HTTPS之外就可以不使用HTTP了,但是,如果攻击者拦截了初始HTTP请求并且可以修改它,他可以提供邮件内容而不是重定向,因此,第一个请求仍然很脆弱。

有标头header可以缓解这个问题,我们也会介绍它们,但首先,让我们关注不使用它们的情况。

如果攻击者可以修改请求,那么你几乎没有办法(除了HSTS),但通常情况下,他更有可能 阅读但不能修改它,为了防止攻击者在收听流量时发生攻击,有一些最佳做法。

(1)仅发送重定向
当你重定向到HTTPS时,请不要随重定向一起发送任何内容,你发送的任何文本都以纯文本形式发送,因此最好将其最小化,将内容加入重定向的请求数据中并不好。

(2)使用安全的cookie
任何未标记为安全的 cookie 都可以通过HTTP和HTTPS发送,反过来,攻击者可以使用它来模仿HTTPS站点上的用户。

确保使用安全的cookie。

6. 你应该使用HTTP吗?
是的,大多数时候。默认情况下,浏览器首先请求HTTP站点,因此你需要支持它。

但有一个例外,如果你有一个API端点,那么你可以(并且应该)完全禁用HTTP,为什么?浏览器遵循重定向,但API客户端可能不会,或者可能将POST重定向为GET。你不希望某些客户端工作,而某些客户端则不工作。

此外,对于API的客户,你提供方案是让任何消费者只可以使用HTTPS。

7. HSTS
好吧,看完上面内容后,你发现了一幅令人担忧的画面,无论你做什么,第一个请求都将是脆弱的,幸运的是,HSTS标头(HTTP Strict Transport Security)目标是解决这个问题。

它的工作原理是指示浏览器不应在后续请求中使用HTTP,而只应使用HTTPS。

这是使用HTTPS响应上的响应标头完成的:

Strict-Transport-Security: max-age=604800;
实际上,即使返回访问者尝试通过HTTP加载网站,也会受到保护。

max-age说明
此部分控制标头有效的时间,在此之后,浏览器将忘记标题并再次请求HTTP站点,每次用户访问页面时都会更新。

604800是一周,如果你使用此功能,常规访问者将受到持续保护。

2592000是一个月

31536000是一年,你不应该使用更多。这已经足够长了,例如,Chrome将 它限制为一年,所以再也没有必要设置它了。

includeSubDomains
如果你指定它,子域也将受到保护,例如,如果你发送标头example.com:

Strict-Transport-Security: max-age=604800; includeSubDomains

然后,它对这几个域名都是有效的:example.com,www.example.com,secure.example.com,www.secure.example.com和所有其他子域。

你应该使用这个子域名选项吗?
这得看情况。这似乎是一件好事,但可能会导致问题。

例如,http://sub.example.com可能适用于某些用户但不适用于其他用户,具体取决于他们之前是否访问过example.com,获得HSTS标头的用户将仅请求HTTPS站点,而其他用户会一直访问HTTP站点,如果此子域又不支持HTTPS,则会产生影响。也就是说,以后所有访问取决于第一次访问的是http还是https,如果第一次是https,以后都是https,如果第一次是http,以后一直是http。

请注意,如果你为域名设置这个选项,又无法为所有子域设置支持HTTPS,唯一的办法是等待所有用户浏览器的标头过期,但这可能需要很长时间。

preload
HSTS的问题在于它只保护回访者,但第一个请求仍然容易受到攻击。

现在浏览器可以不先访问它们的情况下知道HSTS标头的域名列表,Google维护了这样的预加载列表,该列表包含在Chrome和其他浏览器中。

这个内置的预加载列表解决了第一个请求的问题。

要获取列表,你需要发送HSTS标头:

1.在根域,比如jdon.com 而不是www.jdon.com
2.最大年龄至少为一年
3.使用includeSubDomains
4.使用preload预加载

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

这解决了一个特别棘手的问题,但你需要谨慎行事,从预加载列表中删除是非常重要的,你仍然需要等待标头过期日期是1年。


HTTPS security best practices - Advanced Web Machi