Strict-Transport-Security 頭

Baseline 已廣泛支援

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2015 年 7 月⁩以來,各瀏覽器均已提供此特性。

HTTP Strict-Transport-Security 響應頭(通常縮寫為 HSTS)通知瀏覽器只能使用 HTTPS 訪問主機,並且將來任何嘗試使用 HTTP 訪問它的請求都應自動升級到 HTTPS。此外,在將來連線到主機時,瀏覽器將不允許使用者繞過安全連線錯誤,例如無效證書。HSTS 僅透過其域名識別主機。

頭型別 響應頭
禁止請求頭

語法

http
Strict-Transport-Security: max-age=<expire-time>
Strict-Transport-Security: max-age=<expire-time>; includeSubDomains
Strict-Transport-Security: max-age=<expire-time>; includeSubDomains; preload

指令

max-age=<expire-time>

瀏覽器應記住只能使用 HTTPS 訪問主機的時間,以秒為單位。

includeSubDomains 可選

如果指定此指令,HSTS 策略也適用於主機域的所有子域。

preload 可選 非標準

有關詳細資訊,請參閱預載入嚴格傳輸安全。使用 preload 時,max-age 指令必須至少為 31536000(1 年),並且必須存在 includeSubDomains 指令。

描述

Strict-Transport-Security 頭通知瀏覽器所有與主機的連線都必須使用 HTTPS。儘管它是一個響應頭,但它不影響瀏覽器如何處理當前響應,而是影響它如何發出未來的請求。

當 HTTPS 響應包含 Strict-Transport-Security 頭時,瀏覽器會將主機的域名新增到其 HSTS 主機持久列表中。如果域名已在列表中,則更新過期時間和 includeSubDomains 指令。主機僅透過其域名識別。IP 地址不能是 HSTS 主機。HSTS 適用於主機的所有埠,無論請求使用了哪個埠。

在載入 http URL 之前,瀏覽器會根據其 HSTS 主機列表檢查域名。如果域名與 HSTS 主機進行不區分大小寫的匹配,或者是指定了 includeSubDomains 的子域,則瀏覽器會將 URL 方案替換為 https。如果 URL 指定埠 80,瀏覽器會將其更改為 443。任何其他顯式埠號保持不變,瀏覽器使用 HTTPS 連線到該埠。

如果連線到 HSTS 主機時發生 TLS 警告或錯誤(例如無效證書),瀏覽器不會向用戶提供繼續或“點選”錯誤訊息的方式,這會損害嚴格安全的意圖。

注意:主機必須僅透過 HTTPS 傳送 Strict-Transport-Security 頭,而不是不安全的 HTTP。如果透過 HTTP 傳送,瀏覽器會忽略該頭,以防止中間人攻擊 (MITM) 更改該頭以使其過早過期,或為不支援 HTTPS 的主機新增該頭。

過期

每次瀏覽器收到 Strict-Transport-Security 頭時,它都會透過將 max-age 新增到當前時間來更新主機的 HSTS 過期時間。對 max-age 使用固定值可以防止 HSTS 過期,因為每個後續響應都會將過期時間推遲到將來。

如果以前傳送過 Strict-Transport-Security 頭的主機的響應中缺少該頭,則以前的頭會一直有效,直到其過期時間。

要停用 HSTS,請設定 max-age=0。這僅在瀏覽器發出安全請求並收到響應頭後才生效。根據設計,您不能透過不安全的 HTTP 停用 HSTS。

子域

includeSubDomains 指令指示瀏覽器也將域的 HSTS 策略應用於其子域。一個針對 secure.example.com 且帶有 includeSubDomains 的 HSTS 策略也適用於 login.secure.example.comadmin.login.secure.example.com。但它不適用於 example.cominsecure.example.com

即使超域使用 includeSubDomains,每個子域主機也應在其響應中包含 Strict-Transport-Security 頭,因為瀏覽器可能在超域之前聯絡子域主機。例如,如果 example.com 包含帶有 includeSubDomains 的 HSTS 頭,但所有現有連結都直接指向 www.example.com,則瀏覽器永遠不會看到 example.com 的 HSTS 頭。因此,www.example.com 也應傳送 HSTS 頭。

瀏覽器獨立儲存每個域和子域的 HSTS 策略,無論 includeSubDomains 指令如何。如果 example.comlogin.example.com 都發送 HSTS 頭,瀏覽器會儲存兩個獨立的 HSTS 策略,它們可以獨立過期。如果 example.com 使用了 includeSubDomains,則如果其中一個策略過期,login.example.com 仍然受到保護。

如果 max-age=0includeSubDomains 沒有效果,因為指定 includeSubDomains 的域會立即從 HSTS 主機列表中刪除;這不會刪除每個子域的單獨 HSTS 策略。

不安全的 HTTP 請求

如果主機接受不安全的 HTTP 請求,它應使用在 Location 頭中具有 https URL 的永久重定向(例如狀態碼 301)進行響應。重定向不得包含 Strict-Transport-Security 頭,因為請求使用了不安全的 HTTP,但該頭必須僅透過 HTTPS 傳送。在瀏覽器遵循重定向並使用 HTTPS 發出新請求後,響應應包含 Strict-Transport-Security 頭,以確保將來嘗試載入 http URL 將立即使用 HTTPS,而無需重定向。

HSTS 的一個弱點是,它直到瀏覽器與主機建立至少一個安全連線並收到 Strict-Transport-Security 頭後才生效。如果瀏覽器在知道主機是 HSTS 主機之前載入不安全的 http URL,則初始請求容易受到網路攻擊。預載入可以緩解此問題。

嚴格傳輸安全示例場景

  1. 在家中,使用者首次訪問 http://example.com/

  2. 由於 URL 方案是 http 且瀏覽器在其 HSTS 主機列表中沒有它,因此連線使用不安全的 HTTP。

  3. 伺服器響應 301 Moved Permanently 重定向到 https://example.com/

  4. 瀏覽器發出新請求,這次使用 HTTPS。

  5. 透過 HTTPS 發出的響應包含該頭

    http
    Strict-Transport-Security: max-age=31536000; includeSubDomains
    

    瀏覽器記住 example.com 是一個 HSTS 主機,並且它指定了 includeSubDomains

  6. 幾周後,使用者在機場並決定使用免費 Wi-Fi。但不知情地,他們連線到一個執行在攻擊者筆記型電腦上的流氓接入點。

  7. 使用者開啟 http://login.example.com/。因為瀏覽器記住 example.com 是一個 HSTS 主機並且使用了 includeSubDomains 指令,所以瀏覽器使用 HTTPS。

  8. 攻擊者使用偽造的 HTTPS 伺服器攔截請求,但沒有該域的有效證書。

  9. 瀏覽器顯示無效證書錯誤,並且不允許使用者繞過它,從而防止他們將密碼提供給攻擊者。

預載入嚴格傳輸安全

Google 維護一個 HSTS 預載入服務。透過遵循指南併成功提交您的域,您可以確保瀏覽器僅透過安全連線連線到您的域。雖然該服務由 Google 託管,但所有瀏覽器都在使用此預載入列表。但是,它不是 HSTS 規範的一部分,不應被視為官方。

示例

使用 Strict-Transport-Security

所有當前和未來的子域都將在 max-age 為 1 年內使用 HTTPS。這會阻止訪問只能透過 HTTP 提供服務的頁面或子域。

http
Strict-Transport-Security: max-age=31536000; includeSubDomains

儘管 1 年的 max-age 對於域來說是可以接受的,但根據 https://hstspreload.org 上的解釋,建議值為兩年。

在以下示例中,max-age 設定為 2 年,並帶有 preload 字尾,這是為了包含在所有主要網路瀏覽器的 HSTS 預載入列表(如 Chromium、Edge 和 Firefox)中所必需的。

http
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

規範

規範
HTTP 嚴格傳輸安全 (HSTS)
# 第 6.1 節

瀏覽器相容性

另見