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

  本文是《9012年了,還不會Https》的後篇,本文着重聊一聊 HTTP Strict Transport Security協議的概念和應用。html

啓用HTTPS還不夠安全

  站點經過HTTPS 對外提供服務,用戶在訪問某站點,每每會直接輸入站點域名,而不是完整的HTTPS地址,站點通常會發送301重定向,要求瀏覽器升級到HTTPS鏈接。nginx

將全部非安全請求重定向到安全URL是常規作法,可是中間人仍然能夠在重定向發生前劫持鏈接。web

  HSTS指示瀏覽器只能使用HTTPS訪問域名,來處理潛在的中間人劫持風險。即便用戶輸入或使用普通的HTTP鏈接,瀏覽器也嚴格將鏈接升級到HTTPS。chrome

HSTS

HSTS是一種可選的安全加強策略,已經由IETF RFC6797中指定。瀏覽器

服務端經過Strict-Transport-Security響應頭來通知客戶端應用 HSTS協議。緩存

Strict-Transport-Security: max-age=31536000; includeSubDomains
# inclueSubDomains 是可選參數,告知瀏覽器將HSTS策略用到當前域的子域。

一旦瀏覽器承認這個響應頭,知曉訪問這個域名的全部請求必須使用HTTPS鏈接,將會在1年時間內緩存這個約定。安全

當支持 HSTS的瀏覽器承認該響應頭:服務器

  • 瀏覽器爲域名存儲(阻止請求使用HTTP鏈接)配置,瀏覽器將強制全部請求經過 HTTPS
  • 瀏覽器阻止用戶使用不安全/無效證書,會顯示禁用提示(容許用戶臨時信任該證書)

由於HSTS策略由客戶端強制執行,有一些前置條件:app

  • 客戶端必須支持 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

相關文章
相關標籤/搜索