你覺得升級HTTPS就萬事大吉了嗎???

大部分同窗應該都知道 HTTP 協議的網站是不安全的,存在中間人劫持的狀況,所以咱們日常開發的網頁都會將 HTTP 協議升級爲 HTTPS,以確保不會被中間人劫持。瀏覽器

注:本文不涉及 HTTPS 的實現原理以及中間人劫持的概念,不瞭解的同窗先去惡補緩存

但是大家覺得這樣就絕對安全了嗎?咱們想一想下面的場景:安全

一般狀況下,咱們打開一個普通的網站多是經過如下幾個方式:bash

  • 直接點擊收藏欄
  • 經過搜索引擎找到
  • 直接輸入域名

當採用 直接輸入域名 的方式時,以下圖所示: 服務器

這時候咱們並無告訴瀏覽器當前請求的網站協議是https,然而咱們最終打開的仍是 https 協議的百度網站。這是爲何呢?

其實就是重定向幫咱們作了肉眼看不見的事情,具體流程見下圖app

那麼這個過程當中第一步就會涉及名文的傳輸,所以有了被中間人攻擊的機會,因此咱們該如何避免這種狀況的出現呢?答案就是本文須要介紹的 HSTS

HSTS

MDN 對 HSTS 的定義很是直白網站

HTTP Strict Transport Security(一般簡稱爲HSTS)是一個安全功能,它告訴瀏覽器只能經過HTTPS訪問當前資源,而不是HTTP搜索引擎

經過定義咱們能夠畫出下面這樣的流程圖spa

當發起 http 的請求,不通過服務器直接變成 HTTPS 將請求發出去。code

具體怎麼才能讓 HSTS 其做用呢?咱們接着看。

Strict-Transport-Security

經過給https協議的網站的response header配置Strict-Transport-Security

Strict-Transport-Security: max-age=<expire-time>; includeSubDomains(可選); preload(可選,非標準)
複製代碼

每一個屬性的定義以下:

  • max-age= -- 在瀏覽器收到這個請求後的秒的時間內有效。
  • -- 若是這個可選的參數被指定,那麼說明此規則也適用於該網站的全部子域名。
  • preload -- 谷歌維護着一個 HSTS 預加載服務。按照指示成功提交你的域名後,瀏覽器將會永不使用非安全的方式鏈接到你的域名。雖然該服務是由谷歌提供的,但全部瀏覽器都有使用這份列表的意向(或者已經在用了)。可是,這不是 HSTS 標準的一部分,也不應被看成正式的內容。

咱們看到百度的網站也設置了Strict-Transport-Security。

表示在172800秒的時間內訪問百度的主頁都是以https的形式,不過他並無設置includeSubDomains這個屬性。

細心的同窗可能發現了,有一種狀況下仍是沒辦法避免中間人劫持。那就是,在用戶第一次訪問網站而且使用 http 協議的狀況下,若是真要全面防止只能經過給域名添加 preload 的方式。具體方法請參加 MDN 添加preload

總結

有了上面的基礎,讓咱們總結一下三種首次訪問的狀況

  1. 沒有HSTS

    1. 瀏覽器發起http請求
    2. 服務端重定向到https
    3. 瀏覽器發起https請求
  2. 有HSTS,沒有preload

    1. 瀏覽器發起http請求
    2. 服務端重定向到https
    3. 瀏覽器發起https請求
    4. 服務器收到https請求,返回數據的同時會添加 strict-transport-security的header,配置參見上文。每次https請求都會刷新這個過時時間。
  3. 有HSTS以及preload(最佳實踐)

    1. 瀏覽器發起http請求
    2. 因爲存在preload,瀏覽器會主動將連接升級爲https。

最後咱們應該注意,在生產環境下使用 HSTS 應當特別謹慎,由於一旦瀏覽器接收到HSTS Header(假若有效期是1年),可是網站的證書又剛好出了問題,那麼用戶將在接下來的1年時間內都沒法訪問到該網站,直到證書錯誤被修復,或者用戶主動清除瀏覽器緩存。

相關文章
相關標籤/搜索