开启HSTS让浏览器强制跳转HTTPS访问

在网站全站HTTPS后,如果用户手动敲入网站的HTTP地址,或者从其它地方点击了网站的HTTP链接,通常依赖于服务端301/302跳转才能使用HTTPS服务。而第一次的HTTP请求就有可能被劫持,导致请求无法到达服务器,从而构成HTTPS降级劫持。这个问题目前可以通过HSTS(HTTP Strict Transport Security,RFC6797)来解决。

HSTS简介

HSTS(HTTP Strict Transport Security)是国际互联网工程组织IETF发布的一种互联网安全策略机制。采用HSTS策略的网站将保证浏览器始终连接到该网站的HTTPS加密版本,不需要用户手动在URL地址栏中输入加密地址,以减少会话劫持风险。

HSTS响应头格式


  1. Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload] 
  • max-age,单位是秒,用来告诉浏览器在指定时间内,这个网站必须通过HTTPS协议来访问。也就是对于这个网站的HTTP地址,浏览器需要先在本地替换为HTTPS之后再发送请求。
  • includeSubDomains,可选参数,如果指定这个参数,表明这个网站所有子域名也必须通过HTTPS协议来访问。
  • preload,可选参数,一个浏览器内置的使用HTTPS的域名列表。

HSTS Preload List

虽然HSTS可以很好的解决HTTPS降级攻击,但是对于HSTS生效前的首次HTTP请求,依然无法避免被劫持。浏览器厂商们为了解决这个问题,提出了 HSTS Preload List 方案:内置一份可以定期更新的列表,对于列表中的域名,即使用户之前没有访问过,也会使用HTTPS协议。

目前这个Preload List由Google Chrome维护,Chrome、Firefox、Safari、IE 11和Microsoft Edge都在使用。如果要想把自己的域名加进这个列表,首先需要满足以下条件:

拥有合法的证书(如果使用SHA-1证书,过期时间必须早于2016年);

  • 将所有HTTP流量重定向到HTTPS;
  • 确保所有子域名都启用了HTTPS;
  • 输出HSTS响应头:
  • max-age不能低于18周(10886400秒);
  • 必须指定includeSubdomains参数;
  • 必须指定preload参数;

即便满足了上述所有条件,也不一定能进入 HSTS Preload List ,更多信息可以查看: https://hstspreload.org/ 。

通过Chrome的 chrome://net-internals/#hsts 工具,可以查询某个网站是否在Preload List之中,还可以手动把某个域名加到本机Preload List。

HSTS缺点

HSTS并不是HTTP会话劫持的完美解决方案。用户首次访问某网站是不受HSTS保护的。这是因为首次访问时,浏览器还未收到HSTS,所以仍有可能通过明文HTTP来访问。

如果用户通过HTTP访问HSTS保护的网站时,以下几种情况存在降级劫持可能:

  • 以前从未访问过该网站
  • 最近重新安装了其操作系统
  • 最近重新安装了其浏览器
  • 切换到新的浏览器
  • 切换到一个新的设备,如:移动电话
  • 删除浏览器的缓存
  • 最近没访问过该站并且max-age过期了

解决这个问题目前有两种方案:

  • 方案一:在浏览器预置HSTS域名列表,就是上面提到的 HSTS Preload List 方案。该域名列表被分发和硬编码到主流的Web浏览器。客户端访问此列表中的域名将主动的使用HTTPS,并拒绝使用HTTP访问该站点。
  • 方案二:将HSTS信息加入到域名系统记录中。但这需要保证DNS的安全性,也就是需要部署域名系统安全扩展。

其它可能存在的问题

由于HSTS会在一定时间后失效(有效期由max-age指定),所以浏览器是否强制HSTS策略取决于当前系统时间。大部分操作系统经常通过网络时间协议更新系统时间,如Ubuntu每次连接网络时,OS X Lion每隔9分钟会自动连接时间服务器。攻击者可以通过伪造NTP信息,设置错误时间来绕过HSTS。

解决方法是认证NTP信息,或者禁止NTP大幅度增减时间。比如:Windows 8每7天更新一次时间,并且要求每次NTP设置的时间与当前时间不得超过15小时。

支持HSTS浏览器

目前主流浏览器都已经支持HSTS特性,具体可参考下面列表:

  • Google Chrome 4及以上版本
  • Firefox 4及以上版本
  • Opera 12及以上版本
  • Safari从OS X Mavericks起
  • Internet Explorer及以上版本

HSTS部署

服务器开启HSTS的方法是:当客户端通过HTTPS发出请求时,在服务器返回的超文本传输协议响应头中包含 Strict-Transport-Security 字段。非加密传输时设置的HSTS字段无效。

最佳的部署方案是部署在离用户最近的位置,例如:架构有前端反向代理和后端Web服务器,在前端代理处配置HSTS是最好的,否则就需要在Web服务器层配置HSTS。如果Web服务器不明确支持HSTS,可以通过增加响应头的机制。如果其他方法都失败了,可以在应用程序层增加HSTS。

HSTS启用比较简单,只需在相应头中加上如下信息:


  1. Strict-Transport-Security: max-age=63072000; includeSubdomains;preload; 

Strict-Transport-Security 是Header字段名, max-age 代表HSTS在客户端的生效时间。 includeSubdomains 表示对所有子域名生效。preload是使用浏览器内置的域名列表。

HSTS策略只能在HTTPS响应中进行设置,网站必须使用默认的443端口;必须使用域名,不能是IP。因此需要把HTTP重定向到HTTPS,如果明文响应中允许设置HSTS头,中间人攻击者就可以通过在普通站点中注入HSTS信息来执行DoS攻击。

Apache上启用HSTS


  1. $ vim /etc/apache2/sites-available/hi-linux.conf 
  2.  
  3. # 开启HSTS需要启用headers模块 
  4. LoadModule headers_module /usr/lib/apache2/modules/mod_headers.so 
  5.  
  6. <VirtualHost *:80> 
  7.   ServerName www.hi-linux.com 
  8.   ServerAlias hi-linux.com 
  9. ... 
  10.  #将所有访问者重定向到HTTPS,解决HSTS首次访问问题。 
  11.   RedirectPermanent / https://www.hi-linux.com/ 
  12. </VirtualHost> 
  13.  
  14. <VirtualHost 0.0.0.0:443> 
  15. ... 
  16. # 启用HTTP严格传输安全 
  17.   Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" 
  18. ... 
  19. </VirtualHost> 

重启Apache服务


  1. $ service apche2 restart 

Nginx上启用HSTS


  1. $ vim /etc/nginx/conf.d/hi-linux.conf 
  2.  
  3. server { 
  4.    listen 443 ssl; 
  5.    server_name www.hi-linux.com; 
  6.    add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"; 
  7. ... 
  8.  
  9. server { 
  10.    listen 80; 
  11.    server_name www.hi-linux.com; 
  12.    return 301 https://www.hi-linux.com$request_uri; 
  13. ... 

重启Nginx服务


  1. $ service nginx restart 

IIS启用HSTS

要在IIS上启用HSTS需要用到第三方模块,具体可参考: https://hstsiis.codeplex.com/

测试设置是否成功

设置完成了后,可以用 curl 命令验证下是否设置成功。如果出来的结果中含有 Strict-Transport-Security 的字段,那么说明设置成功了。


  1. $ curl -I https://www.hi-linux.com 
  2. HTTP/1.1 200 OK 
  3. Server: nginx 
  4. Date: Sat, 27 May 2017 03:52:19 GMT 
  5. Content-Type: text/html; charset=utf-8 
  6. ... 
  7. Strict-Transport-Security: max-age=63072000; includeSubDomains; preload 
  8. X-Frame-Options: deny 
  9. X-XSS-Protection: 1; mode=block 
  10. X-Content-Type-Options: nosniff 
  11. ... 

对于 HSTS 以及 HSTS Preload List ,建议是只要不能确保永远提供HTTPS服务,就不要启用。因为一旦HSTS生效,之前的老用户在 max-age 过期前都会重定向到HTTPS,造成网站不能正确访问。唯一的办法是换新域名。

本文作者:佚名

来源:51CTO

时间: 2024-11-05 18:51:53

开启HSTS让浏览器强制跳转HTTPS访问的相关文章

JavaScript实现强制重定向至HTTPS页面_javascript技巧

有时候需要把网页强制切换成HTTPS,即使用户已经访问了HTTP的版本.原因可能是你不想让用户使用HTTP来访问,因为它不安全.要做到这个很简单,如果不想用PHP或者Apache的mod_rewrite来做这件事,用Javascript也可以.代码如下: <script type="text/javascript"> var targetProtocol = "https:"; if (window.location.protocol != target

阿里云SLB上http强制跳转到https问题处理

背景:    最近一客户有一个需求,需要将外网所有http访问请求强制跳转到https,公网出口使用阿里云SLB,证书放在SLB上,SLB后端实例为ECS(webserver)web服务使用nginx, 网络拓扑图如下: 问题:SLB上https:443端口监控检测失败,https跳转不成功 状态: 访问网站时浏览器报502错误 排查过程: 根据502错误,判断是后端实例有问题 1 查看nginx服务是否有正常启动 2.首先查看后端实例上是否有开启443端口 3 查看nginx重定向配置: 发现

百度率先将来自360综合搜索的搜索需求强制跳转到百度首页

百度搜索与360综合搜索开始不断出招反制对方,百度率先将来自360综合搜索的搜索需求强制跳转到百度首页,360综合搜索则相继撤下安全网址导航上的百度搜索相关内容,平静多时的中国互联网再度燃起硝烟,一场"3B大战"(360 VS Baidu百度)一触即发.太平洋(601099,股吧)电脑网实时关注"3B大战"事态发展,为大家带来第一手相关消息. 最新消息: 1.360综合搜索官微宣布:8月29日下午4点,将就360搜索作出重要说明. 360搜索官方微博:今天下午4点,

java-HTTPClient可否保持一个会话,就好像浏览器自动跳转、或执行JS

问题描述 HTTPClient可否保持一个会话,就好像浏览器自动跳转.或执行JS 在写一个网页获取的java程序时,用到了HTTPClient包,现在出现这样的问题,可能有一些网站防止获取,采用了一些跳转操作,用httpclient提交了请求后,返回的状态码是200,但这个网页中又加入了一些JS代码,比如: window.setTimeout('document.getElementById(""formxh4t"").submit();'3000); 这样也完成了

js实现浏览器倒计时跳转页面效果_javascript技巧

本文实例为大家分享了js浏览器倒计时跳转页面效果,供大家参考,具体内容如下 效果图: <!DOCTYPE html> <html> <head> <title>浏览器对象</title> <meta http-equiv="Content-Type" content="text/html; charset=gb123"/> </head> <body> <H4>

两款JS脚本判断手机浏览器类型跳转WAP手机网站_javascript技巧

随着移动设备的普及,企业的网络宣传已经不能局限在PC端,而需要同时在移动端有所建树.对于公司网站来说,以前都是做的PC端的,当然手机等移动端也可以访问,但是用户体验肯定不如完全适合的手机端来的方便.我们在给自己的网站做了WAP手机网站之后,如果有用户通过手机访问我们的企业顶级域名网站,那就判断跳转到专为的WAP网站. 这里老左整理到目前自己在使用的2种JS脚本,因为之前一直有朋友跟我要,所以这里分享出来. 第一种:直接JS脚本 <script type="text/javascript&q

JS脚本根据手机浏览器类型跳转WAP手机网站(两种方式)_javascript技巧

随着移动互联网的不断普及,企业的网络宣传不仅只局限在PC端,还要在移动端发展.我们在自己的网站做了WAP手机完整之后,如果有用户通过手机访问我们的企业顶级域名网站,就要判断跳转到专为的WAP网站,下面小编通过两种方式介绍根据手机浏览器类型跳转WAP手机网站,具体内容如下. 第一种方式:直接JS脚本 <script type="text/javascript"> try { var urlhash = window.location.hash; if (!urlhash.ma

两种手机浏览器判断跳转WAP网站JS文件

这里我们只需要用简单的JS判断就可以实现跳转,下面2个方法是老蒋以前有用过的,有需要的朋友可以参考加入到网站中使用.   第一种:    代码如下 复制代码 function uaredirect(murl){ try { if(document.getElementById("bdmark") != null){ return; } var urlhash = window.location.hash; if (!urlhash.match("fromapp"))

javascript-c#如何获得需要浏览器来跳转的链接呢

问题描述 c#如何获得需要浏览器来跳转的链接呢 我想得到我提取出来的网络链接的真正的链接,但是试过很多方法都不行,只有放浏览器里,让他反应才可以,但是这样太坑爹了,求大神们有什么好办法没有 链接1:http://ai.taobao.com/auction/edetail.htm?e=js3icWfJZ4%2FghojqVNxKsYSJDZ1adjmS4mujNrE3oq%2BLltG5xFicObalFqTViQTOxN35oEuRTJew2QavlD7IKn8nMt0sZy5n3YqzTNAI