• HTTP Strict Transport Security (HSTS) in ASP.NET Core


      本文是《9012年了,还不会Https》的后篇,本文着重聊一聊 HTTP Strict Transport Security协议的概念和应用。

    启用HTTPS还不够安全

      站点通过HTTPS 对外提供服务,用户在访问某站点,往往会直接输入站点域名,而不是完整的HTTPS地址,站点一般会发送301重定向,要求浏览器升级到HTTPS连接。

    将所有非安全请求重定向到安全URL是常规做法,但是中间人仍然可以在重定向发生前劫持连接。

      HSTS指示浏览器只能使用HTTPS访问域名,来处理潜在的中间人劫持风险。即使用户输入或使用普通的HTTP连接,浏览器也严格将连接升级到HTTPS。

    HSTS

    HSTS是一种可选的安全增强策略,已经由IETF RFC6797中指定。

    服务端通过Strict-Transport-Security响应头来通知客户端应用 HSTS协议。

    Strict-Transport-Security: max-age=31536000; includeSubDomains
    # inclueSubDomains 是可选参数,告知浏览器将HSTS策略用到当前域的子域。

    一旦浏览器认可这个响应头,知晓访问这个域名的所有请求必须使用HTTPS连接,将会在1年时间内缓存这个约定。

    当支持 HSTS的浏览器认可该响应头:

    • 浏览器为域名存储(阻止请求使用HTTP连接)配置,浏览器将强制所有请求通过 HTTPS
    • 浏览器阻止用户使用不安全/无效证书,会显示禁用提示(允许用户临时信任该证书)

    因为HSTS策略由客户端强制执行,有一些前置条件:

    • 客户端必须支持 HSTS 协议
    • 必须要有一次成功的HTTPS请求,这样才能建立HSTS 策略

    Preload HSTS

    细心的你可能发现,HSTS还是存在一个薄弱漏洞,那就是浏览器没有当前HSTS信息,或者第一次访问; 或者新操作系统,浏览器重装,清除浏览器缓存;HSTS信息的max-age过期;

    依然需要一次明文HTTP请求和重定向才能升级到HTTPS并 刷新HSTS信息,这一次依然给攻击者可乘之机,针对以上攻击,HSTS的应对办法是在浏览器内置一个域名列表,这个列表内域名,浏览器都会使用HTTPS发起连接,这个列表由Chrome维护,主流浏览器均在使用。

    Nginx

    在Nginx中设置 HSTS相对简单:

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    # always 参数确保所有的响应都有 STS Header, 旧版本(低于1.7.5)不支持always参数。

    nginx add_header 的继承规则:

     如果某个配置块包含一个add_header 指令,那么将不会继承上层的headers, 因此你需要在内部配置块重申 add_header 指令。

    server {
        listen 443 ssl;
    
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    
        # This 'location' block inherits the STS header
        location / {
            root /usr/share/nginx/html;
        }
    
        # Because this 'location' block contains another 'add_header' directive,
        # we must redeclare the STS header
        location /servlet {
            add_header X-Served-By "My Servlet Handler";
            add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
            proxy_pass http://localhost:8080;
        }
    }

    ASP.NETCore的福利时间

    若使用 Kestrel 作为边缘(face-to-internet) web服务器, 参见下面的服务配置

    • 为STS header设置了preload参数,Preload不是RFC HSTS规范的一部分,但是浏览器支持在全新安装时预加载HSTS网站
    • 指定子域或排除的子域 使用HSTS协议
    • 设置浏览器缓存 [访问站点的请求均使用HTTPS协议] 这一约定的时间,默认是30天。
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    
        services.AddHsts(options =>
        {
            options.Preload = true;
            options.IncludeSubDomains = true;
            options.MaxAge = TimeSpan.FromDays(60);
            options.ExcludedHosts.Add("example.com");
            options.ExcludedHosts.Add("www.example.com");
        });
    
        services.AddHttpsRedirection(options =>
        {
            options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
            options.HttpsPort = 5001;
        });
    }

    请注意: UseHsts 对于本地回送 hosts 并不生效

    • localhost: IPv4回送地址
    • 127.0.0.1    IPv4回送地址
    • [::1]             IPv6回送地址

    这也是开发者在本地启动时 抓不到  Strict-Transport-Security 响应头的原因。

    下面两动图演示用户首次、后续 直接输入域名访问HTTPS+HSTS站点的过程, 请注意响应码的差异。

    -   动图1 (浏览器无站点HSTS信息): HTTP协议请求----> 返回301,要求重定向使用HTTPS协议 -----> 使用HTTPS协议请求, 被nginx 种下HSTS信息

    -  动图2 (浏览器存在站点HSTS信息): HTTP 协议请求----> 307 internal redirect (浏览器监测到存在站点HSTS信息,直接更改为HTTPS发起请求)------> 使用HTTPS协议请求

     

    + nginx 启用HSTS:  https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/

    + chrome清除HSTS信息: https://www.ssl2buy.com/wiki/how-to-clear-hsts-settings-on-chrome-firefox-and-ie-browsers

  • 相关阅读:
    OpenCV基本函数学习
    OpenCV:概述、结构和内容
    NS2典型例子简单分析
    NS2仿真过程中需要的语言及基本组件
    洛谷 P2393 yyy loves Maths II
    洛谷 P1922 女仆咖啡厅桌游吧
    洛谷 P2559 [AHOI2002]哈利·波特与魔法石
    洛谷 P1301 魔鬼之城
    洛谷 P2383 狗哥玩木棒
    洛谷 P2298 Mzc和男家丁的游戏
  • 原文地址:https://www.cnblogs.com/JulianHuang/p/12156997.html
Copyright © 2020-2023  润新知