为什么我们要使用HTTP Strict Transport Security?
?
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,用戶可能在開始跳轉前,通過沒有加密的方式和服務器對話,比如,用戶輸入http://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來發起連接。比如,用戶點擊超鏈接或在地址欄輸入 http://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://開頭的鏈接為http://,達到阻止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請求。
我們繼續看看這次請求的其他響應:
可以看到支付寶站點服務器是支持hsts功能的,在其響應頭中插入了:Strict-Transport-Security,并且設置這個頭部的有效期,只要不手動清空緩存,那么在這個有效期內,chrome瀏覽器都會將所有發送這個站點的http請求在內部轉換成https再發送出去。
瀏覽器在收到帶有Strict-Transport-Security響應頭的報文后,就會將這個站點加入到hsts緩存中,下次以http訪問的時候就會被自動轉換成https。
我們這時查看以下hsts的緩存中是不是有了?www.alipay.com
正如你所見:www.alipay.com已經被加入到了chrome瀏覽器的緩存中。
這時候在未清空瀏覽器緩存的前提下再次訪問?www.alipay.com?
看到了吧,熟悉的307響應碼,瀏覽器做了內部轉換,將http轉換成https。
3). 其他?
臉書www.facebook.com是已經加入到chrome瀏覽器hsts preload list中的。
正在上傳…重新上傳取消?
注意到沒,信息很詳細哦!
看看我大百度呢?
清空chrome瀏覽器緩存,在地址欄鍵入www.baidu.com:
正在上傳…重新上傳取消?
正在上傳…重新上傳取消?
很遺憾,我大百度也不在chrome hsts preload list中。
在看看這次請求中的其他響應報文呢:
正在上傳…重新上傳取消?
也沒有看到 Strict-Transport-Security的影子。
來自:訪問的文章審核中... - FreeBuf網絡安全行業門戶
最后附上chrome的hsts地址:chrome://net-internals/#hsts
然后如何配置HSTS呢?
nginx配置參數:
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains" always;可以參考這篇:
開啟HSTS讓瀏覽器強制跳轉HTTPS訪問 - luckc# - 博客園
開啟HSTS讓瀏覽器強制跳轉HTTPS訪問
在網站全站HTTPS后,如果用戶手動敲入網站的HTTP地址,或者從其它地方點擊了網站的HTTP鏈接,通常依賴于服務端301/302跳轉才能使用HTTPS服務。而第一次的HTTP請求就有可能被劫持,導致請求無法到達服務器,從而構成HTTPS降級劫持。這個問題目前可以通過HSTS(HTTP Strict Transport Security,RFC6797)來解決。
HSTS簡介
HSTS(HTTP Strict Transport Security)是國際互聯網工程組織IETF發布的一種互聯網安全策略機制。采用HSTS策略的網站將保證瀏覽器始終連接到該網站的HTTPS加密版本,不需要用戶手動在URL地址欄中輸入加密地址,以減少會話劫持風險。
HSTS響應頭格式
Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload]-
max-age,單位是秒,用來告訴瀏覽器在指定時間內,這個網站必須通過HTTPS協議來訪問。也就是對于這個網站的HTTP地址,瀏覽器需要先在本地替換為HTTPS之后再發送請求。
-
includeSubDomains,可選參數,如果指定這個參數,表明這個網站所有子域名也必須通過HTTPS協議來訪問。
-
preload,可選參數,一個瀏覽器內置的使用HTTPS的域名列表。
HSTS Preload List
雖然HSTS可以很好的解決HTTPS降級攻擊,但是對于HSTS生效前的首次HTTP請求,依然無法避免被劫持。瀏覽器廠商們為了解決這個問題,提出了HSTS Preload List方案:內置一份可以定期更新的列表,對于列表中的域名,即使用戶之前沒有訪問過,也會使用HTTPS協議。
目前這個Preload List由Google Chrome維護,Chrome、Firefox、Safari、IE 11和Microsoft Edge都在使用。如果要想把自己的域名加進這個列表,首先需要滿足以下條件:
-
擁有合法的證書(如果使用SHA-1證書,過期時間必須早于2016年);
-
將所有HTTP流量重定向到HTTPS;
-
確保所有子域名都啟用了HTTPS;
-
輸出HSTS響應頭:
-
max-age不能低于18周(10886400秒);
-
必須指定includeSubdomains參數;
-
必須指定preload參數;
即便滿足了上述所有條件,也不一定能進入HSTS Preload List,更多信息可以查看:https://hstspreload.org/。
通過Chrome的chrome://net-internals/#hsts工具,可以查詢某個網站是否在Preload List之中,還可以手動把某個域名加到本機Preload List。
HSTS缺點
HSTS并不是HTTP會話劫持的完美解決方案。用戶首次訪問某網站是不受HSTS保護的。這是因為首次訪問時,瀏覽器還未收到HSTS,所以仍有可能通過明文HTTP來訪問。
如果用戶通過HTTP訪問HSTS保護的網站時,以下幾種情況存在降級劫持可能:
-
以前從未訪問過該網站
-
最近重新安裝了其操作系統
-
最近重新安裝了其瀏覽器
-
切換到新的瀏覽器
-
切換到一個新的設備,如:移動電話
-
刪除瀏覽器的緩存
-
最近沒訪問過該站并且max-age過期了
解決這個問題目前有兩種方案:
方案一:在瀏覽器預置HSTS域名列表,就是上面提到的HSTS Preload List方案。該域名列表被分發和硬編碼到主流的Web瀏覽器。客戶端訪問此列表中的域名將主動的使用HTTPS,并拒絕使用HTTP訪問該站點。
方案二:將HSTS信息加入到域名系統記錄中。但這需要保證DNS的安全性,也就是需要部署域名系統安全擴展。
其它可能存在的問題
由于HSTS會在一定時間后失效(有效期由max-age指定),所以瀏覽器是否強制HSTS策略取決于當前系統時間。大部分操作系統經常通過網絡時間協議更新系統時間,如Ubuntu每次連接網絡時,OS X Lion每隔9分鐘會自動連接時間服務器。攻擊者可以通過偽造NTP信息,設置錯誤時間來繞過HSTS。
解決方法是認證NTP信息,或者禁止NTP大幅度增減時間。比如:Windows 8每7天更新一次時間,并且要求每次NTP設置的時間與當前時間不得超過15小時。
支持HSTS瀏覽器
目前主流瀏覽器都已經支持HSTS特性,具體可參考下面列表:
-
Google Chrome 4及以上版本
-
Firefox 4及以上版本
-
Opera 12及以上版本
-
Safari從OS X Mavericks起
-
Internet Explorer及以上版本
HSTS部署
服務器開啟HSTS的方法是:當客戶端通過HTTPS發出請求時,在服務器返回的超文本傳輸協議響應頭中包含Strict-Transport-Security字段。非加密傳輸時設置的HSTS字段無效。
最佳的部署方案是部署在離用戶最近的位置,例如:架構有前端反向代理和后端Web服務器,在前端代理處配置HSTS是最好的,否則就需要在Web服務器層配置HSTS。如果Web服務器不明確支持HSTS,可以通過增加響應頭的機制。如果其他方法都失敗了,可以在應用程序層增加HSTS。
HSTS啟用比較簡單,只需在相應頭中加上如下信息:
Strict-Transport-Security: max-age=63072000; includeSubdomains;preload;Strict-Transport-Security是Header字段名,max-age代表HSTS在客戶端的生效時間。?includeSubdomains表示對所有子域名生效。preload是使用瀏覽器內置的域名列表。
HSTS策略只能在HTTPS響應中進行設置,網站必須使用默認的443端口;必須使用域名,不能是IP。因此需要把HTTP重定向到HTTPS,如果明文響應中允許設置HSTS頭,中間人攻擊者就可以通過在普通站點中注入HSTS信息來執行DoS攻擊。
Apache上啟用HSTS
$ vim /etc/apache2/sites-available/hi-linux.conf# 開啟HSTS需要啟用headers模塊LoadModule headers_module /usr/lib/apache2/modules/mod_headers.so<VirtualHost *:80>ServerName www.hi-linux.comServerAlias hi-linux.com...#將所有訪問者重定向到HTTPS,解決HSTS首次訪問問題。RedirectPermanent / https://www.hi-linux.com/</VirtualHost><VirtualHost 0.0.0.0:443>...# 啟用HTTP嚴格傳輸安全Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"...</VirtualHost>重啟Apache服務
$ service apche2 restartNginx上啟用HSTS
$ vim /etc/nginx/conf.d/hi-linux.confserver {listen 443 ssl;server_name www.hi-linux.com;add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";...}server {listen 80;server_name www.hi-linux.com;return 301 https://www.hi-linux.com$request_uri;...}重啟Nginx服務
$ service nginx restartIIS啟用HSTS
要在IIS上啟用HSTS需要用到第三方模塊,具體可參考:https://hstsiis.codeplex.com/
測試設置是否成功
設置完成了后,可以用curl命令驗證下是否設置成功。如果出來的結果中含有Strict-Transport-Security的字段,那么說明設置成功了。
$ curl -I https://www.hi-linux.comHTTP/1.1 200 OKServer: nginxDate: Sat, 27 May 2017 03:52:19 GMTContent-Type: text/html; charset=utf-8...Strict-Transport-Security: max-age=63072000; includeSubDomains; preloadX-Frame-Options: denyX-XSS-Protection: 1; mode=blockX-Content-Type-Options: nosniff...對于HSTS以及HSTS Preload List,建議是只要不能確保永遠提供HTTPS服務,就不要啟用。因為一旦HSTS生效,之前的老用戶在max-age過期前都會重定向到HTTPS,造成網站不能正確訪問。唯一的辦法是換新域名。
總結
以上是生活随笔為你收集整理的为什么我们要使用HTTP Strict Transport Security?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle exec编译失效,编译or
- 下一篇: Junit4中Test Suite的用法