關于HSTS安全協(xié)議的全面詳細解析
HTTP 嚴格傳輸安全(HSTS)是一種安全功能,web 服務器通過它來告訴瀏覽器僅用 HTTPS 來與之通訊,而不是使用 HTTP。HSTS 是網(wǎng)站從 HTTP 到 HTTPS 中網(wǎng)站性能及安全優(yōu)化非常重要的一個步驟,能夠解決和兼容 HTTPS 中的一些不足之處。HSTS 在全站 HTTPS 下有一個較大的正向作用,推薦使用。
一、HSTS 是什么?
國際互聯(lián)網(wǎng)工程組織 IETE 正在推行一種新的 Web安全協(xié)議HTTP Strict Transport Security(HSTS)。采用 HSTS 協(xié)議的網(wǎng)站將保證瀏覽器始終連接到該網(wǎng)站的 HTTPS 加密版本,不需要用戶手動在 URL 地址欄中輸入加密地址。該協(xié)議將幫助網(wǎng)站采用全局加密,用戶看到的就是該網(wǎng)站的安全版本。
HSTS 的作用是強制客戶端(如瀏覽器)使用 HTTPS 與服務器創(chuàng)建連接。服務器開啟 HSTS 的方法是,當客戶端通過 HTTPS 發(fā)出請求時,在服務器返回的超文本傳輸協(xié)議響應頭中包含 Strict-Transport-Security 字段。非加密傳輸時設置的 HSTS 字段無效。
HTTPS 最典型的用戶訪問過程
通常我們訪問一個網(wǎng)站時,一般在瀏覽器中只輸入網(wǎng)站地址,而不輸入?yún)f(xié)議名。比如訪問合肥網(wǎng)站建設公司夢揚科技網(wǎng)站,如果直接輸入網(wǎng)址 https://e926.com 或 e926.com 時,這就給了中間人攻擊的一個機會,重定向會可能會被破壞,從而定向到一個惡意站點而不是應該訪問的加密頁面。HTTP 嚴格傳輸安全(HSTS)功能使 Web 服務器告知瀏覽器絕不使用 HTTP 訪問,在瀏覽器端自動將所有到該站點的 HTTP 訪問替換為 HTTPS 訪問。
即使你打開網(wǎng)站看到的是全站 HTTPS 狀態(tài) ,你是因為我們在服務器上做過301/302 跳轉(zhuǎn)到 https://www.e926.com這個地址的, HTTPS 網(wǎng)站的做法是對用戶的 HTTP 訪問做 302 跳轉(zhuǎn)到 HTTPS,并重新建連。
那么問題也就來了,在這個跳轉(zhuǎn)的過程中就有兩個不足之處:
- 整個通信過程中的前兩個 RT 是沒有意義的;
- 使用了不安全的 HTTP 通信,萬一你是在提交敏感數(shù)據(jù)呢。
HSTS 的出現(xiàn)就是解決這些問題的。HSTS 的作用除了節(jié)省 HTTPS 通信 RT 和強制使用 HTTPS ,還包括:
- 阻止基于SSLStrip 的中間人攻擊;
- 萬一證書有錯誤,則顯示錯誤,用戶不能回避警告。
HSTS 的工作機制可描述如下:服務器端配置支持 HSTS 后,會在給瀏覽器返回的 HTTP 首部中攜帶 HSTS 字段。瀏覽器獲取到該信息后,會將所有 HTTP 訪問請求在內(nèi)部做307跳轉(zhuǎn)到 HTTPS,而無需任何網(wǎng)絡過程,從而提高了兼容性,這個機制對于不支持 HTTPS 的搜索引擎來說也是非常友好的做法。
目前大部分瀏覽器對 HSTS 的支持已經(jīng)相當完美,具體各瀏覽器和版本的支持情況可以在http://caniuse.com/#search=HSTS上查看。 但是 HSTS 是有缺陷的,第一次訪問網(wǎng)站的客戶端,HSTS 并不工作。 要解決這個問題,就要了解我們下面要講解的 HSTS preload list。
HSTS preload list 是什么?
HSTS preload list 是 Chrome 瀏覽器中的 HSTS 預載入列表,在該列表中的網(wǎng)站,使用 Chrome 瀏覽器訪問時,會自動轉(zhuǎn)換成 HTTPS。Firefox、Safari、Edge 瀏覽器也會采用這個列表。
加入 HSTS preload list 所需條件:
- 有效的證書;
- 將所有 HTTP 流量重定向到 HTTPS;
- 確保所有子域名啟用 HTTPS,特別是 www 子域名。
同時輸出的 HSTS 響應頭部需要滿足以下條件:
- max-age 至少需要 18 周,10886400 秒
- 必須指定 includeSubdomains 參數(shù)
- 必須支持 preload 參數(shù)
一個典型滿足 HSTS preload list 的響應頭部為:Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
從申請到審核通過,時間在幾天到幾周不等。值得一提的是,從審核通過到正式加入到 Chrome 的 stable release 版本中還需要一段時間,因為要經(jīng)過 canary、dev、beta 以及 stable progression。
HSTS 的優(yōu)勢及必要性
簡單說就是強制客戶端使用 HTTPS 訪問頁面。有效避免了中間人對 80 端口的劫持。但是這里存在一個問題:如果用戶在劫持狀態(tài),并且沒有訪問過源服務器,那么源服務器是沒有辦法給客戶端種下 Strict-Transport-Security 響應頭的(都被中間人擋下來了)。
啟用 HSTS 不僅僅可以有效防范中間人攻擊,同時也為瀏覽器節(jié)省來一次 302/301 的跳轉(zhuǎn)請求,收益還是很高的。我們的很多頁面,難以避免地出現(xiàn) http 的鏈接,比如 help 中的鏈接、運營填寫的鏈接等,這些鏈接的請求都會經(jīng)歷一次 302,對于用戶也是一樣,收藏夾中的鏈接保存的可能也是 http 的。
307 狀態(tài)碼
在 GET、HEAD 這些冪等的請求方式上,302、303、307 沒啥區(qū)別,而對于 POST 就不同了,大部分瀏覽器 都會 302 會將 POST 請求轉(zhuǎn)為 GET,而 303 是規(guī)范強制規(guī)定將 POST 轉(zhuǎn)為 GET 請求,請求地址為 header 頭中的 Location,307 則不一樣,規(guī)范要求瀏覽器繼續(xù)向 Location 的地址 POST 內(nèi)容。
而在 HSTS 中,307 可以被緩存,緩存時間根據(jù) max-age 而定,一般建議緩存 1 年甚至更長。
HSTS 存在的坑
- 純 IP 的請求,HSTS 沒法處理,比如 http://2.2.2.2 , 即便響應頭中設置了 STS,瀏覽器也不會理會(未測試)
- HSTS 只能在 80 和 443 端口之間切換,如果服務是 8080 端口,即便設置了 STS,也無效(未測試)
- 如果瀏覽器證書錯誤,一般情況會提醒存在安全風險,然是依然給一個鏈接進入目標頁,而 HSTS 則沒有目標頁入口,所以一旦證書配置錯誤,就是很大的故障了
- 如果服務器的 HTTPS 沒有配置好就開啟了 STS 的響應頭,并且還設置了很長的過期時間,那么在你服務器 HTTPS 配置好之前,用戶都是沒辦法連接到你的服務器的,除非 max-age 過期了。
- HSTS 能讓你的網(wǎng)站在 ssllab 上到 A+
寫在最后:HSTS 在全站 HTTPS 下有一個較大的正向作用,推薦使用。