簡體   English   中英

為什么在 HTTP 響應中應該同時使用 no-cache 和 no-store?

[英]Why both no-cache and no-store should be used in HTTP response?

我被告知要防止用戶信息泄漏,僅響應“無緩存”是不夠的。 “無商店”也是必要的。

Cache-Control: no-cache, no-store

閱讀此規范http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html后,我仍然不太清楚為什么。

我目前的理解是它僅適用於中間緩存服務器。 即使響應“無緩存”,中間緩存服務器仍然可以將內容保存到非易失性存儲中。 中間緩存服務器將決定是否將保存的內容用於后續請求。 但是,如果響應中包含“no-store”,則中間緩存服務器不應該存儲內容。 因此,它更安全。

我們需要“無緩存”和“無存儲”還有其他原因嗎?

我必須澄清no-cache並不意味着不緩存 事實上,這意味着在對每個請求使用您可能擁有的任何緩存響應之前“使用服務器重新驗證”。

另一方面, must-revalidate僅在資源被認為陳舊時才需要重新驗證。

如果服務器說資源仍然有效,那么緩存可以用它的表示進行響應,從而減輕服務器重新發送整個資源的需要。

no-store實際上是完整的不緩存指令,旨在防止以任何形式的緩存存儲表示。

我隨便說,但請在 RFC 2616 HTTP 規范中注意這一點:

歷史緩沖區可以存儲這樣的響應作為其正常操作的一部分

但這在較新的 RFC 7234 HTTP 規范中被省略,可能是為了使no-store更強大,請參閱:

http://tools.ietf.org/html/rfc7234#section-5.2.1.5

在某些情況下,即使Cache-Control: no-cache在響應頭中,IE6 仍會緩存文件。

no-cacheW3C 狀態

如果 no-cache 指令未指定字段名稱,則緩存不得使用響應來滿足后續請求,而無需與源服務器成功重新驗證。

在我的應用程序中,如果您訪問了帶有no-cache標頭的頁面,然后注銷並在瀏覽器中回擊,IE6 仍會從緩存中獲取該頁面(無需向服務器發送新的/驗證請求)。 添加no-store標頭阻止了它這樣做。 但是如果你相信 W3C 的話,實際上沒有辦法控制這種行為:

歷史緩沖區可以存儲這樣的響應作為其正常操作的一部分。

瀏覽器歷史記錄和普通 HTTP 緩存之間的一般差異在規范的特定子部分中進行了描述。

HTTP 1.1 規范

無店

no-store指令的目的是防止無意中釋放或保留敏感信息(例如,在備份磁帶上)。 no-store 指令適用於整個消息,可以在響應或請求中發送。 如果在請求中發送,則緩存不得存儲此請求或對它的任何響應的任何部分。 如果在響應中發送,則緩存不得存儲此響應或引發它的請求的任何部分。 該指令適用於非共享和共享緩存。 “不得存儲”在此上下文中意味着緩存不得有意將信息存儲在非易失性存儲中,並且必須盡最大努力在轉發信息后盡快從易失性存儲中刪除信息。 即使此指令與響應相關聯,用戶也可能在緩存系統之外顯式存儲此類響應(例如,使用“另存為”對話框)。 歷史緩沖區可以存儲這樣的響應作為其正常操作的一部分。 該指令的目的是滿足某些用戶和服務作者的既定要求,他們擔心通過對緩存數據結構的意外訪問而意外發布信息。 雖然在某些情況下使用此指令可能會改善隱私,但我們警告說,它無論如何都不是確保隱私的可靠或充分機制。 特別是,惡意或受損的緩存可能無法識別或遵守此指令,並且通信網絡可能容易受到竊聽。

如果您想阻止所有緩存(例如,在使用后退按鈕時強制重新加載),您需要:

  • IE 無緩存

  • Firefox 無商店

我的信息在這里:

http://blog.httpwatch.com/2008/10/15/two-important-differences-between-firefox-and-ie-caching/

no-store在正常情況下不是必需的,它會損害速度和可用性。 它旨在用於 HTTP 響應包含如此敏感的信息,以至於根本不應將其寫入磁盤緩存的情況,無論對用戶造成的負面影響如何。

這個怎么運作:

  • 通常,即使用戶代理(例如瀏覽器)確定不應緩存響應,由於用戶代理內部的原因,它仍可能將其存儲到磁盤緩存中。 此版本可用於“查看源代碼”、“返回”、“頁面信息”等功能,其中用戶不一定再次請求該頁面,但瀏覽器不會將其視為新的頁面視圖並且為用戶當前正在查看的相同版本提供服務是有意義的。

  • 使用no-store將阻止存儲該響應,但這可能會影響瀏覽器提供“查看源代碼”、“返回”、“頁面信息”等信息而不向服務器發出新的單獨請求的能力,這是不可取的. 換句話說,用戶可能會嘗試查看源,如果瀏覽器沒有將其保存在內存中,他們要么被告知這是不可能的,要么會導致對服務器的新請求。 因此,只有當這些功能無法正常或快速運行所阻礙的用戶體驗被確保內容不存儲在緩存中的重要性所抵消時,才應使用no-store

我目前的理解是它只是用於中間緩存服務器。 即使響應“無緩存”,中間緩存服務器仍然可以將內容保存到非易失性存儲中。

這是不正確的。 與 HTTP 1.1 兼容的中間緩存服務器將遵守no-cachemust-revalidate指令,確保內容不被緩存。 使用這些指令將確保響應不會被任何中間緩存緩存,並且所有后續請求都被發送回源服務器。

如果中間緩存服務器不支持 HTTP 1.1,那么您將需要使用Pragma: no-cache並希望最好。 請注意,如果它不支持 HTTP 1.1,那么no-store無論如何都無關緊要。

對於 chrome,no-cache 用於在重新訪問時重新加載頁面,但如果您返回歷史記錄(后退按鈕),它仍然會緩存它。 要重新加載歷史記錄頁面,請使用 no-store。 IE 需要必須重新驗證才能在所有場合工作。

所以只是為了確保避免我經常使用的所有錯誤和誤解

Cache-Control: no-store, no-cache, must-revalidate

如果我想確保它重新加載。

如果緩存系統正確實現了 no-store,那么您就不需要 no-cache。 但並非所有人都這樣做。 此外,一些瀏覽器實現了無緩存,就像沒有存儲一樣。 因此,雖然不是嚴格要求,但包括兩者可能是最安全的。

請注意,當嘗試下載通過 https 提供的文件並且服務器發送Cache-Control: no-cachePragma: no-cache標頭時,從版本 5 到 8 的 Internet Explorer 將引發錯誤。

請參閱http://support.microsoft.com/kb/812935/en-us

Cache-Control: no-storePragma: private似乎是最接近的仍然有效的東西。

最初我們多年前使用 no-cache 並且確實遇到了某些瀏覽器陳舊內容的一些問題......不幸的是,不記得具體細節。

從那以后,我們決定只使用 no-store。 從那以后,任何瀏覽器或中介機構再也沒有回頭或遇到過陳舊內容的任何問題。

這個空間肯定是由實現的現實與各種 RFC 中所寫的內容所主導的。 許多代理尤其傾向於認為,通過用自己的策略替換他們應該遵循的策略,他們在“提高性能”方面做得更好。

更糟糕的是,在某些情況下,不能使用 no-cache,但 no-store 可以:

http://faindu.wordpress.com/2008/04/18/ie7-ssl-xml-flex-error-2032-stream-error/

為了回答這個問題,這里有兩個參與者,客戶端(請求)和服務器(響應)。

客戶:

客戶端只能使用一種緩存方法進行請求。 有不同的方法,如果未指定,將使用default

  • 默認:檢查瀏覽器緩存:
    1. 如果緩存並且“新鮮”:從緩存中返回。
    2. 如果緩存,陳舊,但仍然“有效”:從緩存返回,並安排一次獲取以更新緩存(供下次使用)。
    3. 如果緩存和陳舊:獲取條件、緩存並返回。
    4. 如果未緩存:獲取、緩存並返回。
  • no-store :獲取並返回。 不要使用緩存存儲。
  • reload :獲取、緩存和返回。 默認-4
  • no-cache :檢查瀏覽器緩存:
    1. 如果緩存:帶條件獲取、緩存並返回。 默認-3
    2. 如果未緩存:獲取、緩存並返回。 默認-4
  • force-cache :檢查瀏覽器緩存:
    1. 如果緩存:無論是否過時都返回它。
    2. 如果不緩存:獲取、緩存並返回。 默認-4
  • only-if-cached :檢查瀏覽器緩存:
    1. 如果緩存:無論是否過時都返回它。
    2. 如果沒有緩存:拋出網絡錯誤。

筆記:

  • 仍然“有效”意味着當前age不在stale-while-revalidate生命周期內。 它需要“重新驗證”,但仍然可以退貨。
  • 這里的“Fetch”,為簡單起見,是“non-conditional network fetch”的縮寫。
  • “帶條件獲取”意味着使用諸如If-Modified-SinceETag之類的標頭進行獲取,以便服務器可以使用304: (Not Modified)進行響應。

https://fetch.spec.whatwg.org/#concept-request-cache-mode

服務器::

現在我們了解了客戶端可以做什么,服務器響應就更有意義了。 查看Cache-Control標頭,如果服務器返回:

  • no-store :告訴客戶端根本不使用緩存
  • no-cache :告訴客戶端它應該執行條件請求並忽略新鮮度
  • max-age :告訴客戶端緩存“新鮮”多長時間
  • stale-while-revalidate :告訴客戶端緩存“有效”多長時間
  • 不可變:永遠緩存

現在我們可以把它們放在一起。 這意味着唯一的可能性是:

  • 非條件網絡獲取
  • 條件網絡獲取
  • 返回過時的緩存
  • 返回陳舊但有效的緩存
  • 返回新的緩存
  • 返回任何緩存

客戶端或服務器的任何組合都可以指定要使用的方法或方法集。 如果服務器返回no-store ,則無論客戶端請求類型如何,它都不會命中緩存。 如果客戶端請求是no-store ,那么無論服務器返回什么,它都不會緩存。 如果客戶端沒有指定請求類型,服務器將使用Cache-Control來指定它。 服務器返回no-cacheno-store是沒有意義的,因為no-store覆蓋了一切 是的,您可能已經同時看到了兩者,並且在損壞的瀏覽器實現之外它是無用的。

在實際使用中,如果您的服務器支持304: Not Modified ,並且您想使用客戶端緩存作為提高速度的一種方式,但仍想強制網絡獲取,請使用no-cache 如果不支持304並且想要強制網絡獲取,請使用no-store 如果您有時可以使用緩存,請使用新鮮度和重新驗證標頭。

實際上,如果您在客戶端上混合使用no-cacheno-store ,幾乎不會發生任何變化。 然后,只發送幾個標頭,瀏覽器將處理不同的內部響應。 如果您使用no-cache然后忘記使用它,則可能會出現問題。 no-cache告訴它將響應存儲在緩存中,以后沒有它的請求可能會觸發內部緩存。

有時您甚至可能希望根據上下文在同一資源上混合方法。 例如,您可能希望在服務工作者和后台同步上使用reload ,但對網頁本身使用default 這是您可以根據自己的喜好操作用戶代理(瀏覽器)緩存的地方。 請記住,服務器通常對緩存的工作方式擁有最終決定權。


TL;DR: no-store覆蓋no-cache 兩者都設置是沒有用的,除非我們談論的是不支持no-store的損壞瀏覽器。

一個很老的話題,但我會分享一些最近的想法:

no-store :不得嘗試存儲任何內容,並且還必須采取措施刪除它可能擁有的任何副本。

no-cache :在沒有先驗證源服務器的情況下,永遠不要使用本地副本。 即使使用新資源,它也可以防止緩存命中的所有可能性。

所以,回答這個問題,只使用其中一個就足夠了。 此外,一些(不是很)最近的作品證明了現在的瀏覽器更加兼容 Cache-Control。

OWASP 對此進行了討論:

緩存控制指令之間有什么區別:no-cache 和 no-store?

響應中的 no-cache 指令表示該響應不得用於為后續請求提供服務,即緩存不得顯示在標頭中設置了此指令的響應,但必須讓服務器為請求提供服務。 no-cache 指令可以包含一些字段名稱; 在這種情況下,響應可以從緩存中顯示,除了指定的應該從服務器提供的字段名稱。 no-store 指令適用於整個消息,並指示緩存不得存儲響應的任何部分或請求它的任何請求。

我對這些指令完全安全嗎?

否。但通常,除了 Expires: 0(或充分回溯的 GMT 日期,例如 UNIX 紀元)之外,還使用 ​​Cache-Control: no-cache, no-store 和 Pragma: no-cache。 即使設置了上述緩存控制指令,非 html 內容類型(如 pdf、word 文檔、excel 電子表格等)也經常被緩存(盡管這因版本和附加使用 must-revalidate、pre-check=0、post-check 而異=0、max-age=0 和 s-maxage=0 在實踐中有時至少會導致在某些情況下由於瀏覽器怪癖和 HTTP 實現而在瀏覽器關閉時刪除文件)。 此外,“自動完成”功能允許瀏覽器緩存用戶在表單輸入字段中輸入的任何內容。 要檢查這一點,表單標記或單個輸入標記應包括 'Autocomplete="Off" ' 屬性。 然而,應該注意的是,這個屬性是非標准的(雖然它被主流瀏覽器支持),所以它會破壞 XHTML 驗證。

來源在這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM