1. 程式人生 > >HTTP Strict Transport Security (HSTS) in ASP.NET Core

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 響應頭的原因。

下面給出啟用了 HSTS的 結果示例:

 

+ 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

&n