HTTP安全標頭及其工作原理(下)
上一篇文章我們對HTTP標頭的安全意義做了介紹,本文將為大家講述有哪些標頭可以起到實際的安全防護作用。
HTTP嚴格傳輸安全性(HSTS)HTTP標頭
顧名思義,HSTS是一種強制瀏覽器使用安全Web連線的機制。近些年,隨著域名劫持、資訊洩漏等網路安全事件的頻繁發生,網站安全也變得越來越重要,也促成了網路傳輸協議從 HTTP 到 HTTPS 再到 HSTS 的轉變。採用HSTS協議的網站將保證瀏覽器始終連線到該網站的HTTPS加密版本,不需要使用者手動在URL位址列中輸入加密地址。
該協議將幫助網站採用全域性加密,使用者看到的就是該網站的安全版本。HSTS的作用是強制客戶端(如瀏覽器)使用HTTPS與伺服器建立連線。伺服器開啟HSTS的方法是,當客戶端通過HTTPS發出請求時,在伺服器返回的超文字傳輸協議響應頭中包含Strict-Transport-Security欄位。非加密傳輸時設定的HSTS欄位無效。
事實上,我們可以將HSTS稱為安全Web連線鏈中的“缺失連結”,為什麼這麼說呢?
通過端到端加密,SSL為安全和授權連線奠定了基礎。在理想的SSL實施中,我們可以確保在傳輸過程中資料不會被第三方更改或監控,或者驗證我們正在與之通訊的人是流量的預期接收者。
上面我之所以說是“理想的SSL實施”,是因為一些Web應用程式僅使用了部分實現,例如僅在登入和結帳頁面中使用了安全連線,這就構成了巨大的安全威脅, HTTP Cookie Hijacking in the Wild (DEF CON 24會議)詳細介紹了部分實現所帶來的風險。
如果我們不強制所有頁面通過安全連線傳輸,攻擊者可以輕鬆轉移瀏覽目標,在不安全的連線上瀏覽網頁,或通過啟動MITM攻擊(如SSL Strip)將HTTPS流量轉換為HTTP。
另外,過期或無效的證書對你的安全連線構成嚴重威脅。如果你的使用者面臨這些容易預防的問題,你的網站聲譽也會受到損害。
有沒有辦法進一步可以改善你網站上的HTTPS保護?
如果要充分利用SSL,則必須將所有HTTP請求轉換為HTTPS,並通過安全連線載入所有影象、指令碼、樣式檔案和其他檔案。另外,你還必須防止使用者解除證書錯誤。
不過手動完成所有這些操作是非常困難的,尤其是在你必須阻止使用者訪問你的網站時出現證書錯誤的情況下。
值得慶幸的是,2012年11月釋出的HSTS規範已經解決這個問題。我們所要做的就是在我們的網頁響應上設定安全標頭(Strict-Transport-Security)。使用此安全標頭,我們可以將瀏覽器指向:
1.將所有請求轉換為HTTPS連線;
2.如果出現證書相關錯誤(例如過期的證書),則無論如何都要阻止使用者瀏覽網站;
3.在指定的時間內快取此設定;
Strict-Transport-Security標頭示例
以下是如何使用此標頭的示例:
Strict-Transport-Security: max-age=31536000;
max-age:該指令允指定了標頭內容儲存在在瀏覽器快取中儲存的時間(以秒為單位)。
HSTS實現中有兩個更重要的規範:includeSubdomains引數和preload引數。我們可以使用includeSubdomains引數在網站的所有子域上執行相同的嚴格且安全的連線。
第一次請求和預載入
我們只能通過安全連線設定HSTS標頭,就像公鑰固定(這是另一個HTTPS安全標頭)一樣,HSTS基於首次使用信任(Trust on First Use,TOFU)。這意味著我們必須在第一次HTTP請求時手動將使用者重定向到我們網站的HTTPS版本。在其響應中,將有一個HSTS標頭,這意味著瀏覽器將其儲存在其快取中。如果下次出現不安全(HTTP)連線時,它將自動重定向到安全連線。
黑客是否可以通過MiTM攻擊覆蓋第一個HTTP請求?
經過測試,黑客是可以通過MiTM攻擊覆蓋第一個HTTP請求的。然而,這一次,HSTS預載列表提供了幫助。
我們需要將preload指令新增到我們的HSTS標頭中,以使網站有資格被包含在HSTS預載入列表中。此時瀏覽器將檢查網站是否包含在列表中,並拒絕通過不安全的連線載入網站。
HSTS預載入列表的附加要求
將我們的網站新增到HSTS預載入列表還有一些要求:
1.你需要提供有效的證書;
2.你必須在同一主機上將HTTP重定向到HTTPS,這意味著example.com的HTTPS流量應通過example.com(而不是通過任何其他域,例如secure.example.com);
3.你必須為所有子域支援HTTPS,尤其是www子域。
4.你必須為HSTS標頭設定以下值:
4.1 max-age必須至少設定為31536000秒(1年);
4.2 必須指定includeSubDomains和preload指令;
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
HTTP公鑰固定(Public Key Pinning)
HTTP公鑰固定(HPKP)是一種安全功能,它告訴Web客戶端將特定加密公鑰與某個Web伺服器相關聯,以降低使用偽造證書進行“MITM攻擊(中間人攻擊)”的風險。
為了理解HTTP公鑰鎖定(HPKP),讓我們看看瀏覽器如何實現SSL握手,這是在建立安全連線之前進行的。
當我們的使用者試圖安全訪問我們的站點時,我們將公鑰傳送給他們,公鑰會確認他們正在與正確的一方進行對話,並將用於加密共享金鑰。我們將其稱為“證書”,它儲存了網站名稱、證書到期日期以及加密金鑰中的位數等資訊。
偽造的證書頒發機構及其所頒發的證書
證書中還有一條附加資訊,當瀏覽器收到我們的證書時,它會檢查我們的證書是否由受信任的證書頒發機構(CA)簽名。簽發給我們證書中的資訊之一便是CA的名稱,瀏覽器將使用該名稱來驗證我們的證書。一旦確認為真實連線,就建立了安全連線。
但是,通過幾個已經發生的安全事件,我們發現無論安全動機如何,其中一個證書頒發機構都可以代表網站簽署證書而不通知網站所有者!以下6個事件可以說明這一點:
1.其中一個例子發生在2011年荷蘭,當時授權證書頒發機構DigiNotar遭到黑客攻擊。黑客入侵數字證書授權系統,分發超過500個欺騙性數字證書給頂級網際網路公司,如谷歌,Mozilla和Skype.這次黑客攻擊發生在2011年6月初,但是DigiNotar直到7月中旬才發現。該公司在當年9月申請破產。其中攻擊者使用這些證書監控多項Google服務,包括30萬個伊朗使用者的Gmail帳戶。
2.在2008年和2011年也發生了類似的事件,2008年10月,StartCom被安全研究人員Mike Zusman發現可以繞過其證書所有權驗證流程,可以為任意域名申請證書,但由於他申請了paypal.com和verisign.com的證書觸發了StartCom高危網站黑名單被發現了此次攻擊並在幾分鐘之內吊銷了所有非法簽發的證書。在2011年,攻擊者又訪問StartCom的根金鑰,獲得了生成、更新或使任何StartCom證書失效的能力。而 StartCom 將從2018年1月1日起停止頒發新證書,並且將僅提供 CRL 和 OCSP 服務兩年。
如果你仍然使用 StartCom 的數碼證書,我們強烈建議你儘快更換其他 SSL 供應商 (e.g. Comodo, Symantec, GeoTrust, etc.) 所提供的數碼證書,以避免出現憑證錯誤的問題或其他影響。
3.2012年5月,火焰病毒(flamer或Skywiper)針對Microsoft 的CA證書採用了MD5碰撞攻擊來攻擊windows update的程式碼簽名機制,影響了整個中東網路。
4.2012年12月,TURKTRUST(土耳其)由於管理失誤下發兩張二級CA證書,其中一個被用於防火牆來進行中間人監控,而被google的扎釘扎技術發現。
5.2013年12月, ANSSI(法國的網路資訊保安局)頒發的二級CA證書被用於該機構中間人監控裝置中,而被google的釘扎技術發現並宣佈吊銷其簽發的二級證書,並限制只能簽發法國地區域名(.fr)的證書。
6.2014年7月,NIC(印度國家資訊中心)的二級CA(NICCA)被入侵,偽造簽發了很多google和yahoo的域名證書,後續有問題的中間證書被吊銷,該機構也被停止了證書籤發,該機構的根證書機構被限制只能簽發幾個印度(.in)的子域名。
如何防止偽造證書
在回答這個問題之前,我們先要問一下瀏覽器如何自動檢測某個特定域的欺詐性頒發證書,甚至將此證書報告給谷歌?
這就要依靠一種稱為HTTP公鑰鎖定(HPKP)的機制,自從Chrome 13中引入此功能以來,網站可以使用Public-Key-Pins響應標頭使瀏覽器知道其證書指紋(雜湊值)。
瀏覽器將這些雜湊值儲存在使用者的計算機上,每次訪問網站時,瀏覽器都會根據證書的公鑰生成雜湊。如果雜湊值與儲存的值不匹配,則不會建立連線,如果設定了report-uri指令,則會將事件報告給URL。
總之,HTTP公鑰鎖定可以保護使用者和網站免受偽造的CA證書的影響。
設定HPKP標頭
Public-Key-Pins是一個安全標頭,我們可以通過安全連線(HTTPS)將HPKP與每個響應一起傳送回去:
Public-Key-Pins: pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="; report-uri="http://example.com/pkp-report"; max-age=10000; includeSubDomains
HPKP指令
HPKP標頭可以使用各種指令,例如max-age和report-uri,以下是一個完整的指令列表。
pin-sha256="<sha256>":這是我們在base64中編碼的證書的公鑰指紋,你可以在此處將多個證書的雜湊值儲存為備份,以防其中一個證書過期。
max-age:這是應該快取此指令的時間長度(以秒為單位)。
includeSubdomains:HTTP公鑰鎖定是否覆蓋子域。
report-uri:如上面的谷歌示例所述,在不匹配的情況下,該指令指定應該將HPKP策略違規報告發送到的URL,違規資訊將使用HTTP POST方法傳送到此URL。
你可以將HTTP公鑰鎖定機制設定為只在報告模式下工作,這意味著如果發生不匹配,瀏覽器仍將建立一個安全連線,但會將違規資訊報告給report-uri指令中指定的URL。
Public-Key-Pins-Report-Only: pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="; report-uri="http://example.com/pkp-report"; max-age=10000; includeSubDomains
根據 RFC 7469 ,你必須設定至少2個引腳。一個用於當前證書,另一個用於備份證書。給定的Pins集包含至少一個不引用證書鏈中的SPKI的Pin。也就是說,主機必須設定備份引腳。
發表在 EvenPaths 上的研究表明,即使在Facebook和WhatsApp等大公司的網頁上,也存在HPKP實施錯誤。這些資訊是使用Alexa Top 100萬域名列表收集的。雖然有些網站沒有在他們的HPKP標頭中固定任何證書,但也有網站固定多達17個。
哪些瀏覽器支援PKP安全標頭?
在閱讀了上述關於HPKP的內容後,我想要告訴你的是,從谷歌Chrome版本69開始,不再支援HPKP,雖然這種機制可以幫助Google捕獲在野外發布的欺詐性證書。
儘管谷歌的這一做法一開始這有點令人驚訝,但如果你仔細想一想它還是有道理的。即使像Facebook這樣資源豐富的公司在實施這種安全措施時也會犯錯誤,它可能過於複雜,無法大規模可靠地使用。
但是,有一個標頭可以提供相同的保護,且不是很複雜,它就是Expect-CT HTTP標頭。
Expect-CT HTTP標頭
取代HPKP的標頭被稱為Expect-CT HTTP標頭,儘管HPKP是一個有用的安全功能,但到目前為止,它並不是檢測CA頒發的證書是否是惡意或阻止它們的唯一方法。通過證書頒發機構授權(CAA)和證書透明度等安全機制,攻擊者仍可以在未經我們許可或不知情的情況下操縱簽發給我們的證書,在某些情況下甚至可以完全阻止CA頒發這些證書。
但是這些Expect-CT HTTP標頭保護措施具體是如何運作的,能否真正取代HPKP呢?
證書透明度日誌
證書透明系統的核心是證書日誌,證書日誌是維護SSL證書記錄的簡單網路服務。這就是為什麼我們要把討論的安全標頭被稱為'Expect-CT',換句話說“期望證書會被提交給證書透明度日誌”。
這些證書透明度日誌可公開訪問,因此管理員可以檢查它們並搜尋自己的域。如果在沒有事先知情或授權的情況下為其域名頒發了證書,他們可以立即採取措施保護其使用者。
當然,CA並沒有動機為已經嚴格監管的證書籤署過程增加更多的複雜性,這就是為什麼谷歌不得不在2018年4月釋出新證書時強制執行CT日誌的原因。
CT日誌的工作原理
證書日誌有三個重要特性,證書透明度為當前的SSL證書系統添加了三個新的功能元件:
· 證書日誌;
· 證書監視器;
·證書稽核員;
這些功能元件代表提供補充監控和審計服務的分立軟體模組。它們不是現有SSL證書系統的替代品或替代品。事實上,這些元件不會改變基本的信任鏈模型,它允許客戶端驗證域並建立與伺服器的安全連線。相反,這些元件通過為公眾監督和整個SSL證書系統的審查提供支援來增強信任鏈模型。
此外,建議網站所有者將Expect-CT標頭新增到他們的響應中。因為瀏覽器會決定提交給他們的證書是否遵循概述的規則,除證書外,瀏覽器還會檢查簽名證書時間戳(SCT)。此資料包含記錄證書的時間戳,而瀏覽器則使用SCT資訊檢查是否符合概述的條件。
使用Expect-CT HTTP標頭有沒有風險?
如果我們在2015年4月的強制性開始日期之前在Google Chrome中為我們的網站頒發了證書,並且將過期日期設定為2005年,則Google無法執行證書透明度規則。否則,這將導致大量完全有效的證書不再可用,即使它們是在CT發明之前釋出的。由於HPKP在Chrome中已棄用,因此無法通知我們網站是否含有非法頒發的證書。
但是,如果我們設定並強制執行Expect-CT標頭,並使用max-age將該指令在瀏覽器中快取一段時間。那麼在連線到我們網站的過程中,凡是不符合CT要求的證書,即使是在2018年4月之前簽署,也不會被接受。通過這種方式,我們消除了在不知情的情況下判定舊證書有效的風險。
我們如何實現Expect-CT標頭?
首先,我們必須確保我們當前的證書支援CT,我們可以通過生成 SSL實驗室報告 來實現。
接下來,我們可以使用如下所示的標頭啟用HTTP響應中的Expect-CT標頭:
Expect-CT: enforce,max-age=30,report-uri="https://ABSOLUTE_REPORT_URL"
Expect-CT標頭有三個指令:
max-age:這表示資料儲存在瀏覽器快取中的持續時間(以秒為單位)。
report-uri:這是違規報告將傳送到的URL,它必須是絕對URL(例如https://example.com/report),而不是相對網址(例如/ report)。
enforce:如果存在不符合CT的證書,則指示是否應該建立連線。
你也可以在單純報告模式下使用此模式,而該模式最初不會強制執行CT要求。
Expect-CT: max-age=30,report-uri="https://ABSOLUTE_REPORT_URL"
如果一切都如預期的那樣,那麼你可以選擇強制執行。
Expect-CT: max-age=30,report-uri="https://ABSOLUTE_REPORT_URL", enforce
Referrer-Policy HTTP標頭
Referer請求標頭由於層級很複雜,容易讓人產生混亂。首先,'referer'就是拼寫錯了的單詞,正確的拼寫應該是' referrer '。儘管這是一個有趣的有趣事實,它也表明糾正一個簡單的錯誤是多麼困難,如HTTP標頭欄位中缺少'r'。如果你還不是很懂,就想象一下,在廣泛的協議中糾正一個關鍵安全漏洞多麼困難吧!
但拼寫錯誤並不是造成此標頭難於被理解的根本原因,至於具體的原因,請先讓我們來看看這個標頭是如何工作的?
Referrer-Policy標頭的工作原理
假設你是網站A的所有者,並且你希望訪問者檢視網站B。此時,你可以通過在主頁上新增指向網站B的超連結來完成此操作。如果使用者單擊該連結,則他們的瀏覽器會自動將Referer標頭新增到請求標頭。此時,它的內容將是網站A的地址。這樣做的好處是,網站B可以通過檢查每個傳入請求的Referer標頭來檢視誰連結到他們的網站。 此時,Referer標頭將被新增到針對樣式、影象、指令碼載入和表單提交的請求中。請求看起來如下:
GET / HTTP/1.1 Host: B.com Referer: A.com
出於安全和隱私等多種原因,你可能希望將資訊隱藏在Referer頭中。
作為響應標頭,Referrer-Policy為你提供了以下選項來幫助控制Referer請求標頭。注意Referrer-Policy是如何用雙r(rr)編寫的。可以說,這隻會增加區分Referer / Referrer拼寫錯誤的難度,儘管這是正確的寫法。
可以在HTTP響應訊息中設定Referrer-Policy標頭,如下所示:
Referrer-Policy: no-referrer
Referrer-Policy指令
以下是Referrer-Policy標頭可以傳送的所有指令資訊:
" " (empty):這表示未設定Referrer-Policy,並且可以通過頁面上的HTML元素設定控制引用的指令。這可以通過使用<meta>標記或使用rel或referrerpolicy屬性為單個HTML標記指定策略來完成。
Referrer-Policy:
no-referrer:即使重定向頁面與主機具有相同的來源,也不會新增任何Referer標頭。
Referrer-Policy: no-referrer
no-referrer-when-downgrade:如果協議降級(從更安全的協議傳遞到安全性較低的協議,例如HTTPS到HTTP),則不會發送Referer標頭,這是所有瀏覽器的預設行為。
Referrer-Policy: no-referrer-when-downgrade
same-origin:如果目標網站具有相同的來源(scheme、域和埠必須匹配),則僅傳送Referer標頭。Referrer-Policy: same-origin
origin:這會截斷Referer標頭中URL的路徑部分,如上所述,origin包括scheme,域和埠。在協議降級期間(從HTTPS切換到HTTP),路徑資訊將被省略,只有原始資料將被髮送到引用程式中的HTTP網站。
Referrer-Policy: origin
strict-origin:該指令將確保當協議安全級別保持不變(例如HTTPS和HTTPS)時,瀏覽器僅將源作為引用傳送,但不會將其傳送到安全級別較低的網站,例如從HTTPS傳送到HTTP。
Referrer-Policy: strict-origin
origin-when-cross-origin:如果目標和主機網站具有相同的來源,則Referer標頭將包含完整的URL。如果兩者具有不同的來源,則只有scheme和域資料將包含在Referer頭中。在協議降級的情況下,Origin資料也將通過Referer頭髮送到請求的HTTP網站。
Referrer-Policy: origin-when-cross-origin
strict-origin-when-cross-origin:使用此指令時,只有在目標和主機網站共享在同一協議安全級別或具有更高的協議安全級別時,才會顯示Referer資料中的Origin資料。
Referrer-Policy: strict-origin-when-cross-origin
unsafe-url:瀏覽器將在從主機到目標網站的每個請求中共享Referer標頭中的完整URL。
你應該注意到,使用此指令,即使從安全連線到不安全連線,也將共享完整的URL。此選項會使你退出瀏覽器的預設行為(避免協議降級中的URL可見性),因此應謹慎使用。
Referrer-Policy: unsafe-url
哪些瀏覽器支援Referrer-Policy安全標頭?
在下圖中,你可以看到哪些瀏覽器完全支援Referrer-Policy,哪些瀏覽器不支援。詳細資訊,請訪問此 連結 。