
我的 Apache 是 2.4.46,使用的是 Openssl 版本 1.1.1f
我已經設定了指令SSLCompression Off
。即使我啟用它,它也會說不支援 SSL 壓縮,我想這很好。
但是,當我使用 Firefox 查看網頁的 HTTP 標頭時,我看到以下回應標頭:
HTTP/2 200 OK
date: Fri, 25 Dec 2020 12:13:58 GMT
server: Apache
expires: -1
cache-control: no-store, no-cache, must-revalidate, max-age=0
pragma: no-cache
content-security-policy: default-src https: 'unsafe-inline' 'unsafe-hashes' 'self'; img-src data: https: 'self'
x-frame-options: DENY
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
strict-transport-security: max-age=63072000; includeSubDomains; preload
referrer-policy: no-referrer
permissions-policy: geolocation=();midi=();notifications=();push=();sync-xhr=(self);microphone=();camera=();magnetometer=();gyroscope=();speaker=(self);vibrate=();fullscreen=(self);payment=();
vary: Accept-Encoding
content-encoding: gzip
content-length: 3299
content-type: text/html; charset=UTF-8
X-Firefox-Spdy: h2
上面寫著:content-encoding: gzip
讓我擔心。
但是,即使我使用 cURL 在 PHP 中使用此腳本來獲取頁面:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//enable headers
curl_setopt($ch, CURLOPT_HEADER, 1);
//get only headers
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 5000);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0");
curl_setopt($ch, CURLOPT_ENCODING, "gzip");
它會傳回這些 HTTP 標頭:
HTTP/2 200
date: Fri, 25 Dec 2020 12:16:45 GMT
server: Apache
set-cookie: __Secure-CCJRLSESSID=g7m99kljvea2g5uk58f5lfskr1; path=/; secure; HttpOnly; SameSite=Lax
expires: -1
cache-control: no-store, no-cache, must-revalidate, max-age=0
pragma: no-cache
content-security-policy: default-src https: 'unsafe-inline' 'unsafe-hashes' 'self'; img-src data: https: 'self'
x-frame-options: DENY
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
strict-transport-security: max-age=63072000; includeSubDomains; preload
referrer-policy: no-referrer
permissions-policy: geolocation=();midi=();notifications=();push=();sync-xhr=(self);microphone=();camera=();magnetometer=();gyroscope=();speaker=(self);vibrate=();fullscreen=(self);payment=();
content-type: text/html; charset=UTF-8
這讓我很困惑。我什至清除了 Firefox 的緩存,但沒有成功。我不想受到犯罪攻擊。反過來,我可以完全停用 gzip。但在此之前,我想知道為什麼會發生這種情況。也許是火狐瀏覽器的錯誤?
更新:
它也發生在鍍鉻中。
mod_deflate 配置:
SSLCompression Off
<IfModule deflate_module>
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
AddOutputFilterByType DEFLATE application/x-font
AddOutputFilterByType DEFLATE application/x-font-opentype
AddOutputFilterByType DEFLATE application/x-font-otf
AddOutputFilterByType DEFLATE application/x-font-truetype
AddOutputFilterByType DEFLATE application/x-font-ttf
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE font/opentype
AddOutputFilterByType DEFLATE font/otf
AddOutputFilterByType DEFLATE font/ttf
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE image/x-icon
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/xml
</IfModule>
答案1
要回答您的問題,了解一些背景會有所幫助:
背景 - 為什麼使用壓縮可能有安全風險?
有一些所謂的“壓縮側通道攻擊”,它們基本上使用壓縮結果來嘗試猜測原始文字。每個的工作原理基本上都是能夠將輸入添加到壓縮中,然後觀察輸出。這是因為許多壓縮演算法的工作原理是識別重複的文字並用引用替換它們,而不是多次完整地重複文字。這會導致訊息變小,但確實帶來了攻擊機會。
這些攻擊是如何進行的?
基本上,如果您猜測部分或全部秘密部分,將其與未知秘密部分一起添加到訊息中,然後觀察加密結果的大小,如果它隨著某些猜測而變小,那麼您必須重複部分訊息因此受益於更高的壓縮。
透過一些猜測,就有可能找出秘密部分。執行此操作取決於是否能夠新增至訊息,但有多種方法可以執行此操作。例如,如果您想知道token
example.com 的 cookie 設置,則發送一條訊息(也許是當人們訪問您完全不相關的網站時發生的隱藏 XHR 訊息?)example.com?token=1
並測量結果訊息大小(因為瀏覽器會自動添加cookie也包含在訊息中)。然後嘗試example.com?token=2
看看它是更大、更小還是相同。對所有可能的值重複此操作,直到找到 cookie 的第一個字符,其中訊息將較小。假設在這個例子中它是token=5
.然後嘗試第二個字元(例如example.com?token=51
,example.com?token=52
...等)。重複此操作,直到您獲得完整的 cookie。
您可以直接測量訊息的長度(例如,如果可以的話,透過觀察加密訊息中間人網路)或發送訊息需要多長時間,以便很好地猜測長度。
HTTP 訊息可以透過多種方式壓縮
壓縮可以在 HTTP 訊息中的不同級別進行:1) 在 SSL/TLS 級別,2) 在 HTTP 正文級別,以及 3) 在 HTTP 標頭級別。
SSL 壓縮
無論底層是 HTTP 訊息,SSL/TLS 壓縮基本上都會發生 - 它是在 SSL/TLS 層級完成的。攻擊就像犯罪基本上阻止了我們使用 SSL/TLS 壓縮,因為它引入了太多的方法來猜測訊息的隱藏部分,基本上使用上述演算法。老實說,SSL/TLS 壓縮的收益並沒有那麼大,特別是如果我們已經使用 gzip 或類似工具在底層 HTTP 級別壓縮了主體響應,因此在加密後再次壓縮它並沒有真正節省那麼多更多數據。所以沒有真正的理由使用它,這給了一個真正的理由不是使用它。應始終關閉 SSL/TLS 壓縮並使用類似工具SSL實驗室來確認這一點。在大多數伺服器中,它預設為關閉狀態,並且已經關閉了一段時間,所以如果它打開了,我們會感到非常驚訝。
HTTP 正文壓縮
HTTP Body 等級的壓縮更有趣。這通常使用 gzip 或更新的 Brotli 演算法,並且是建議在大多數情況下打開,因為網路效能的提升非常顯著。這是因為 HTTP 主體通常很大(特別是回應主體),而網路通常相對較慢,因此透過網路傳送較小的尺寸會帶來真正的好處。現在是的,理論上這很容易受到類似的攻擊(所謂的違規攻擊還有時間變體)-但前提是秘密資料再次位於主體中(因此任何相同的猜測在壓縮後都可以看到更小)。因此,風險要小得多,因為大多數回應不包含秘密資料(例如,您最後一次看到cookie 列印到頁面上的螢幕是什麼時候?),而標頭中的cookie 通常總是包含在內,並且佔訊息的較大比例。
當然,如果您有一些秘密資訊列印到螢幕上(您的姓名、社會安全號碼、DoB、銀行詳細資訊等),那麼它可能很容易受到攻擊,也許應該考慮不要使用HTTP 壓縮這些回應,但這些回應非常不典型因此禁用 HTTP 壓縮每一個回應很少是正確的答案。即使您在螢幕上顯示秘密訊息,也有更好的選擇:例如,根本不在螢幕上顯示該數據,或至少不在螢幕上顯示全部數據(例如,除最後4 位數字之外的所有數字),不允許顯示使用者回應資料例如,同時在螢幕上顯示,以隨機字元填滿資料或新增速率限制通常是更好的選擇。
回到你的問題
因此,回答你的問題,SSL 壓縮和 HTTP 正文壓縮是兩個不同的東西,前者應該是離開和後者在(除了在真正安全的應用程式中,儘管有收益,但不想冒這個風險,但即使如此,通常也有更好的方法來處理這個問題)。
最後,一些有關 HTTP 標頭壓縮的額外信息
為了結束這個故事,讓我們來談談 HTTP 標頭壓縮,因為如上所述,它們通常包含攻擊者認為有價值的 cookie 秘密。
直到最近,HTTP/1.1 仍然是使用的主要版本,它不允許這樣做,所以這裡沒有太多可談的。這些以完全未壓縮的形式發送(如果使用 HTTPS,則使用 SSL/TLS 加密),因此不易受到側通道壓縮風險的影響(假設未使用 SSL 壓縮)。
與 HTTP 主體相比,這些通常也非常小,因此沒有人真正擔心將它們壓縮得太多。然而,隨著用於組成網頁的資源數量的增加(現在超過 100 個資源並不罕見),始終來回發送幾乎相同的 HTTP 標頭會產生大量冗餘(您是否看到過大小)例如,用戶代理標頭隨每個單一請求一起發送,但對於所有這些請求都不會更改? )。
因此,較新的 HTTP/2 和即將發布的 HTTP/3 協定確實允許 HTTP 標頭壓縮,但它們專門選擇了不易受到這些攻擊的壓縮演算法(HTTP/2 的 HPACK 和 HTTP/3 的類似 QPACK)。順便說一句,這是一個明確的選擇,因為 HTTP/2 所基於的早期 SPDY 協定確實使用了 gzip,因此很容易受到攻擊。因此,當它被標記時,必須進行更改,作為將其標準化為 HTTP/2 的一部分。
為什麼不總是使用“安全壓縮”?
那為什麼我們不能對 HTTP 回應主體使用安全壓縮技術(如 HPACK 或 QPACK)來避免這種情況呢?它們是非常特定的壓縮技術,使用字典或已知和重複的值。這對於值很少且大量重複的 HTTP 標頭來說效果很好,但對於更通用的 HTTP 正文回應來說,這並不是一個真正的選項,因為每個回應可能完全不同。
希望這能解釋一些事情並回答您的問題。
答案2
針對犯罪的攻擊CVE-2012-4929是關於加密壓縮的標頭,而不正確混淆未加密資料的長度,這使得可以揭示明文標頭(透過猜測)。
在您的情況下,內容被壓縮,壓縮資料的大小(長度)被添加為另一個標頭,然後所有這些都被加密。這不容易受到 CRIME 攻擊,因為未加密資料的長度永遠不會被洩露。