鉴于通过互联网这一庞大管道传输的个人数据量,加密是我们不能也不应轻易忽视的问题。现代浏览器提供了多种机制,可用于确保用户数据在传输过程中的安全:安全 Cookie 和严格传输安全是其中最重要的两种机制。它们可让您无缝保护用户,将其连接升级到 HTTPS,并保证用户数据绝不会以明文形式发送。
为什么您应该关注?请考虑以下因素:
通过未加密的 HTTP 连接传送网页,或多或少就像是将未封口的信封交给您在街上看到的第一个人,而这个人看起来正朝着邮局的方向走。如果运气好,她可能会亲自把信送到目的地,也可能会把信交给她看到的下一个朝正确方向走的人。该用户也可能会这样做,依此类推。
在这个临时链条中,大多数陌生人都是值得信赖的,绝不会窥探或篡改您的公开信。不过,信件转手的次数越多,能够完全访问您所发送信件的人数就越多。最终,信件的预期收件人很可能会收到一些邮件,但这些邮件是否与您最初寄出的邮件相同,则是一个悬而未决的问题。也许你该把信封封好…
中间人
无论好坏,互联网的很大一部分都依赖于陌生人的可信度。服务器之间不直接连接,而是通过路由器将请求和响应传递给另一个路由器,就像玩传话游戏一样。
您可以使用 traceroute 查看这些跃点的实际运行情况。从我的计算机到 HTML5Rocks 的路由大致如下所示:
$ traceroute html5rocks.com
traceroute to html5rocks.com (173.194.71.102), 30 hops max, 60 byte packets
1 router1-lon.linode.com (212.111.33.229) 0.453 ms
2 212.111.33.233 (212.111.33.233) 1.067 ms
3 217.20.44.194 (217.20.44.194) 0.704 ms
4 google1.lonap.net (193.203.5.136) 0.804 ms
5 209.85.255.76 (209.85.255.76) 0.925 ms
6 209.85.253.94 (209.85.253.94) 1.226 ms
7 209.85.240.28 (209.85.240.28) 48.714 ms
8 216.239.47.12 (216.239.47.12) 22.575 ms
9 209.85.241.193 (209.85.241.193) 36.033 ms
10 72.14.233.180 (72.14.233.180) 43.222 ms
11 72.14.233.170 (72.14.233.170) 43.242 ms
12 *
13 lb-in-f102.1e100.net (173.194.71.102) 44.523 ms
13 跳其实不算多。但是,如果我通过 HTTP 发送请求,那么每个中间路由器都可以完全访问我的请求和服务器的响应。所有数据都以未加密的明文形式传输,任何中间方都可能充当中间人,读取我的数据,甚至在传输过程中操纵数据。
更糟糕的是,这种拦截几乎无法检测到。经过恶意修改的 HTTP 响应看起来与有效响应完全相同,因为没有任何机制可以确保接收到的数据与发送的数据完全相同。如果有人决定为了好玩而把我的互联网搞得一团糟,那么我或多或少会倒霉。
这条线路安全吗?
从明文 HTTP 切换到安全的 HTTPS 连接是防范中间人攻击的最佳方式。HTTPS 连接会在发送任何数据之前对整个通道进行端到端加密,从而使您与目标之间的机器无法读取或修改传输中的数据。
HTTPS 提供的安全性基于公钥和私钥加密密钥的概念。对细节的深入讨论(令人高兴的是)远远超出了本文的范围,但核心前提相当简单:使用给定公钥加密的数据只能使用相应的私钥解密。当浏览器启动 HTTPS 握手以创建安全信道时,服务器会提供一个证书,该证书会向浏览器提供所有必要信息,以便通过检查服务器是否拥有正确的私钥来验证其身份。从该时间点开始,所有通信都以某种方式加密,以证明请求已传送到认证服务器,并且响应是从认证服务器收到的。
因此,HTTPS 可在一定程度上确保您正在与您认为正在与之通信的服务器进行通信,并且没有其他人在监听或篡改网络上的数据。这种加密是网络安全的绝对前提条件;如果您的应用目前不是通过 HTTPS 交付,则很容易受到攻击。解决问题。Ars Technica 提供了一份获取和安装证书(免费)的指南,建议您查看该指南以了解技术细节。配置因提供商和服务器而异,但证书请求流程在所有情况下都相同。
默认安全
在您请求并安装证书后,请确保您的用户能从您的辛勤工作中受益:通过 HTTP 重定向的魔力,将现有用户透明地迁移到 HTTPS 连接,并确保 Cookie 仅通过安全连接传递。
请走这边
当用户访问 http://example.com/ 时,通过发送带有适当 Location 标头的 301 Moved
Permanently 响应,将用户重定向到 https://example.com/:
$ curl -I http://mkw.st/
HTTP/1.1 301 Moved Permanently
Server: nginx/1.3.7
...
Keep-Alive: timeout=20
Location: https://mkw.st/
您可以在 Apache 或 Nginx 等服务器中轻松设置此类重定向。
例如,从 http://example.com/ 重定向到 https://example.com/ 的 Nginx 配置如下所示:
server {
listen [YOUR IP ADDRESS HERE]:80;
server_name example.com www.example.com;
location "/" {
rewrite ^(.*) https://www.example.com$1 permanent;
}
}
锁上饼干罐
借助 Cookie,我们能够通过无状态 HTTP 协议为用户提供顺畅的登录体验。存储在 Cookie 中的数据(包括会话 ID 等敏感信息)会随每个请求一起发送,以便服务器了解当前正在响应哪个用户。确保用户通过 HTTPS 访问我们的网站后,我们还应确保 Cookie 中存储的敏感数据仅通过安全连接传输,绝不以明文形式发送。
设置 Cookie 通常涉及如下所示的 HTTP 标头:
set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT
您可以通过添加一个关键字来指示浏览器将 Cookie 的使用限制为安全会话:
Set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT; secure
使用 secure 关键字设置的 Cookie 绝不会通过 HTTP 发送。
关闭打开的窗口
透明地重定向到 HTTPS 意味着,用户在您网站上的绝大多数时间都将使用安全连接。不过,它确实会留下一个小的攻击窗口:初始 HTTP 连接是完全开放的,容易受到 SSL 剥离和相关攻击。由于中间人可以完全访问初始 HTTP 请求,因此它可以充当您与服务器之间的代理,无论服务器的意图如何,都会让您保持不安全的 HTTP 连接。
您可以要求浏览器强制执行 HTTP 严格传输安全协议 (HSTS),从而降低此类攻击的风险。发送 Strict-Transport-Security HTTP 标头会指示浏览器在客户端执行 HTTP 到 HTTPS 重定向,而无需接触网络(这也有利于提升性能;最好的请求就是您不必发出的请求):
$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000
支持此标头的浏览器(目前有 Firefox、Chrome 和 Opera:caniuse 提供了详细信息)会记录此特定网站已请求仅通过 HTTPS 访问,这意味着无论用户如何访问该网站,都将通过 HTTPS 访问。即使她在浏览器中输入 http://example.com/,最终也会进入 HTTPS 网站,而不会建立 HTTP 连接。更棒的是,如果浏览器检测到无效证书(可能试图伪造服务器的身份),用户将无法通过 HTTP 继续访问;要么全部通过,要么全部不通过,这非常棒。
浏览器将在 max-age 秒(在本例中约为一个月)后使服务器的 HSTS 状态过期;请将此值设置为合理的高值。
您还可以通过在标头中添加 includeSubDomains 指令,确保源的所有子网域都受到保护:
$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000
安全前行
HTTPS 是唯一能确保您发送的数据完整到达预期接收方的方式。您现在应该为网站和应用设置安全连接。这个过程非常简单,有助于确保客户数据的安全。建立加密通道后,无论用户通过何种方式访问您的网站,您都应通过发送 301 HTTP 响应,将用户透明地重定向到此安全连接。然后,通过在设置 Cookie 时添加 secure 关键字,确保用户的所有敏感会话信息仅使用该安全连接。完成上述所有操作后,请确保您的用户永远不会意外掉队:通过发送 Strict-Transport-Security 标头,确保用户的浏览器执行正确的操作,从而保护用户。
设置 HTTPS 并不需要太多工作,但对您的网站及其用户大有裨益。这非常值得一试。
资源
- StartSSL 提供免费的网域验证证书。免费服务,无可匹敌。当然,您也可以升级到更高级别的验证,而且价格合理。
- SSL 服务器测试:为服务器设置 HTTPS 后,请通过 SSL Labs 的服务器测试进行验证,确保设置正确。您将获得一份详细的报告,其中会显示您是否真的已启动并运行。
- Ars Technica 最近发表的文章《使用 SSL/TLS 保护 Web 服务器》值得一读,其中提供了有关设置服务器的具体细节的更多背景信息。
- HTTP 严格传输安全协议规范 (RFC6797) 值得浏览,其中包含您可能需要的所有关于
Strict-Transport-Security标头的技术信息。 - 在您真正了解自己在做什么之后,下一步可能是宣传您的网站只能通过一组特定的证书访问。IETF 正在开展一些工作,让您可以通过
Public-Key-Pins标头实现此目的;虽然还处于早期阶段,但很有趣,值得关注。