HTTP Strict Transport Security (通常簡稱為HSTS) 是一個安全功能,它告訴瀏覽器只能通過HTTPS訪問當前資源, 禁止HTTP方式。
0×01. Freebuf百科:什麼是Strict-Transport-Security
我摘自owasp上的一段定義:
HTTP Strict Transport Security (HSTS) is an opt-in security enhancement that is specified by a web application through the use of a special response header. Once a supported browser receives this header that browser will prevent any communications from being sent over HTTP to the specified domain and will instead send all communications over HTTPS. It also prevents HTTPS click through prompts on browsers.The specification has been released and published end of 2012 as RFC 6797 (HTTP Strict Transport Security (HSTS)) by the IETF. (Reference see in the links at the bottom.)
一個網站接受一個HTTP的請求,然後跳轉到HTTPS,用戶可能在開始跳轉前,通過沒有加密的方式和伺服器對話,比如,用戶輸入https://foo.com或者直接foo.com。這樣存在中間人攻擊潛在威脅,跳轉過程可能被惡意網站利用來直接接觸用戶信息,而不是原來的加密信息。網站通過HTTP Strict Transport Security通知瀏覽器,這個網站禁止使用HTTP方式加載,瀏覽器應該自動把所有嘗試使用HTTP的請求自動替換為HTTPS請求。
0×02. 我們為什麼需要開啟Strict-Transport-Security
想想這樣一種場景:
有的網站開啟了https,但為了照顧用戶的使用體驗(因為用戶總是很賴的,一般不會主動鍵入https,而是直接輸入域名, 直接輸入域名訪問,默認就是http訪問)同時也支持http訪問,當用戶http訪問的時候,就會返回給用戶一個302重定向,重定向到https的地址,然後後續的訪問都使用https傳輸,這種通信模式看起來貌似沒有問題,但細緻分析,就會發現種通信模式也存在一個風險,那就是這個302重定向可能會被劫持篡改,如果被改成一個惡意的或者釣魚的https站點,然後,你懂得,一旦落入釣魚站點,數據還有安全可言嗎?
對於篡改302的攻擊,建議伺服器開啟HTTP Strict Transport Security功能,這個功能的含義是:
當用戶已經安全的登錄開啟過htst功能的網站 (支持hsts功能的站點會在響應頭中插入:Strict-Transport-Security) 之後,支持htst的瀏覽器(比如chrome. firefox)會自動將這個域名加入到HSTS列表,下次即使用戶使用http訪問這個網站,支持htst功能的瀏覽器就會自動發送https請求(前提是用戶沒有清空緩存,如果清空了緩存第一次訪問還是明文,後續瀏覽器接收到伺服器響應頭中的Strict-Transport-Security,就會把域名加入到hsts緩存中,然後才會在發送請求前將http內部轉換成https),而不是先發送http,然後重定向到https,這樣就能避免中途的302重定向URL被篡改。進一步提高通信的安全性。
上面是我自己的理解,下面是owasp中文站點關於hsts的描述:
HSTS的作用是強制客戶端(如瀏覽器)使用HTTPS與伺服器創建連接。伺服器開啟HSTS的方法是,當客戶端通過HTTPS發出請求時,在伺服器返回的超文本傳輸協議響應頭中包含Strict-Transport-Security欄位。非加密傳輸時設置的HSTS欄位無效。
比如,https://example.com/ 的響應頭含有Strict-Transport-Security: max-age=31536000; includeSubDomains。這意味著兩點:
在接下來的一年(即31536000秒)中,瀏覽器只要向example.com或其子域名發送HTTP請求時,必須採用HTTPS來發起連接。比如,用戶點擊超連結或在地址欄輸入 https://www.example.com/ ,瀏覽器應當自動將 http 轉寫成 https,然後直接向 https://www.example.com/ 發送請求。
在接下來的一年中,如果 example.com 伺服器發送的TLS證書無效,用戶不能忽略瀏覽器警告繼續訪問網站。
HSTS可以用來抵禦SSL剝離攻擊。SSL剝離攻擊是中間人攻擊的一種,由Moxie Marlinspike於2009年發明。他在當年的黑帽大會上發表的題為「New Tricks For Defeating SSL In Practice」的演講中將這種攻擊方式公開。SSL剝離的實施方法是阻止瀏覽器與伺服器創建HTTPS連接。它的前提是用戶很少直接在地址欄輸入https://,用戶總是通過點擊連結或3xx重定向,從HTTP頁面進入HTTPS頁面。所以攻擊者可以在用戶訪問HTTP頁面時替換所有https://開頭的連結為https://,達到阻止HTTPS的目的。
HSTS可以很大程度上解決SSL剝離攻擊,因為只要瀏覽器曾經與伺服器創建過一次安全連接,之後瀏覽器會強制使用HTTPS,即使連結被換成了HTTP
另外,如果中間人使用自己的自籤名證書來進行攻擊,瀏覽器會給出警告,但是許多用戶會忽略警告。HSTS解決了這一問題,一旦伺服器發送了HSTS欄位,用戶將不再允許忽略警告。
0×03. Strict-Transport-Security的一些不足
用戶首次訪問某網站是不受HSTS保護的。這是因為首次訪問時,瀏覽器還未收到HSTS,所以仍有可能通過明文HTTP來訪問。解決這個不足目前有兩種方案,一是瀏覽器預置HSTS域名列表,Google Chrome、Firefox、Internet Explorer和Spartan實現了這一方案。二是將HSTS信息加入到域名系統記錄中。但這需要保證DNS的安全性,也就是需要部署域名系統安全擴展。截至2014年這一方案沒有大規模部署。
由於HSTS會在一定時間後失效(有效期由max-age指定),所以瀏覽器是否強制HSTS策略取決於當前系統時間。部分作業系統經常通過網絡時間協議更新系統時間,如Ubuntu每次連接網絡時,OS X Lion每隔9分鐘會自動連接時間伺服器。攻擊者可以通過偽造NTP信息,設置錯誤時間來繞過HSTS。解決方法是認證NTP信息,或者禁止NTP大幅度增減時間。比如Windows 8每7天更新一次時間,並且要求每次NTP設置的時間與當前時間不得超過15小時
0×04. 我的一些測試
1). 測試1
目標域名:portal.fraudmetrix.cn (這個站點不支持hsts功能) 同盾科技的風險控制管理系統(打個軟廣,同盾科技,基於大數據,專注反欺詐)。
第一次訪問:在瀏覽器地址欄鍵入:portal.fraudmetrix.cn
可以看到:
這個域名並不在chrome瀏覽器的hsts的緩存中,也不在hsts中的preload list中(像facebook、twitter等網站已經內置在preload list中,所以每次請求這些站點的時候瀏覽器都會自動將http 轉換成htttps),所以不會在發送請求前將http轉換成https請求。
我們來把這個站點手動加入到chrome瀏覽器的hsts緩存中:
在未清空chrome瀏覽器歷史記錄的前提下,我們再次訪問這個站點:
可以看到,一個307 響應碼,這是chrome瀏覽器的內部轉換,將http轉換成https後再發送請求。
備註:為什麼我們要求在未清空chrome瀏覽器的緩存前訪問呢?
因為如果清空了chrome瀏覽器的緩存之後,我們手動加入到hsts緩存中的域名就會被清除,也就不會看到預期的效果了。
2). 測試2
我們先清空chrome瀏覽器的緩存,然後在瀏覽器的地址欄中鍵入 www.alipay.com
可以看到www.alipay.com(支付寶)這個站點並沒有在chrome 瀏覽器的內置的preload list中,所以第一次訪問的時候,chrome瀏覽器並不會將http轉換成https。
而是由前端的F5的負載均衡(BigIP)器將http請求重定向到https請求。