136

我被告知要防止用户信息泄漏,仅响应“无缓存”是不够的。“无商店”也是必要的。

Cache-Control: no-cache, no-store

阅读此规范http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html后,我仍然不太清楚为什么。

我目前的理解是它仅适用于中间缓存服务器。即使响应“无缓存”,中间缓存服务器仍然可以将内容保存到非易失性存储中。中间缓存服务器将决定是否将保存的内容用于后续请求。但是,如果响应中包含“no-store”,则中间缓存服务器不应该存储内容。因此,它更安全。

我们需要“无缓存”和“无存储”还有其他原因吗?

4

12 回答 12

97

我必须澄清这no-cache并不意味着不缓存。实际上,这意味着在每次请求中使用您可能拥有的任何缓存响应之前“与服务器重新验证”。

must-revalidate另一方面,仅当资源被认为是陈旧的时才需要重新验证。

如果服务器说资源仍然有效,那么缓存可以用它的表示来响应,从而减轻服务器重新发送整个资源的需要。

no-store实际上是完整的不缓存指令,旨在防止以任何形式的缓存存储表示。

我随便说,但请在 RFC 2616 HTTP 规范中注意这一点:

历史缓冲区可以存储这些响应作为其正常操作的一部分

但这在较新的 RFC 7234 HTTP 规范中被省略,可能是为了变得no-store更强大,请参阅:

https://www.rfc-editor.org/rfc/rfc7234#section-5.2.1.5

于 2012-06-27T15:13:16.833 回答
51

在某些情况下,IE6 仍然会缓存文件,即使Cache-Control: no-cache在响应标头中也是如此。

W3Cno-cache状态:

如果 no-cache 指令未指定字段名称,则缓存不得使用响应来满足后续请求,而无需与源服务器成功重新验证。

在我的应用程序中,如果您访问了带有no-cache标题的页面,然后注销然后在浏览器中回击,IE6 仍会从缓存中获取该页面(无需向服务器发送新/验证请求)。添加no-store标题阻止了它这样做。但如果你相信 W3C 的话,实际上没有办法控制这种行为:

历史缓冲区可以存储这些响应作为其正常操作的一部分。

浏览器历史记录和普通 HTTP 缓存之间的一般差异在规范的特定小节中描述。

于 2009-05-15T03:35:48.280 回答
15

HTTP 1.1 规范

无商店

无商店的目的指令是为了防止无意中释放或保留敏感信息(例如,在备份磁带上)。no-store 指令适用于整个消息,并且可以在响应或请求中发送。如果在请求中发送,缓存不得存储此请求的任何部分或对它的任何响应。如果在响应中发送,缓存不得存储此响应或引发它的请求的任何部分。该指令适用于非共享和共享缓存。在这种情况下,“不得存储”意味着缓存不得有意将信息存储在非易失性存储中,并且必须尽最大努力在转发信息后尽快从易失性存储中删除信息。即使该指令与响应相关联,用户可能会在缓存系统之外显式存储这样的响应(例如,使用“另存为”对话框)。历史缓冲区可以存储这些响应作为其正常操作的一部分。该指令的目的是满足某些用户和服务作者的既定要求,他们担心通过对缓存数据结构的意外访问而意外释放信息。虽然在某些情况下使用该指令可能会改善隐私,但我们警告说,它绝不是确保隐私的可靠或充分机制。特别是,恶意或受损的缓存可能无法识别或遵守此指令,并且通信网络可能容易受到窃听。历史缓冲区可以存储这些响应作为其正常操作的一部分。该指令的目的是满足某些用户和服务作者的既定要求,他们担心通过对缓存数据结构的意外访问而意外释放信息。虽然在某些情况下使用该指令可能会改善隐私,但我们警告说,它绝不是确保隐私的可靠或充分机制。特别是,恶意或受损的缓存可能无法识别或遵守此指令,并且通信网络可能容易受到窃听。历史缓冲区可以存储这些响应作为其正常操作的一部分。该指令的目的是满足某些用户和服务作者的既定要求,他们担心通过对缓存数据结构的意外访问而意外释放信息。虽然在某些情况下使用该指令可能会改善隐私,但我们警告说,它绝不是确保隐私的可靠或充分机制。特别是,恶意或受损的缓存可能无法识别或遵守此指令,并且通信网络可能容易受到窃听。虽然在某些情况下使用该指令可能会改善隐私,但我们警告说,它绝不是确保隐私的可靠或充分机制。特别是,恶意或受损的缓存可能无法识别或遵守此指令,并且通信网络可能容易受到窃听。虽然在某些情况下使用该指令可能会改善隐私,但我们警告说,它绝不是确保隐私的可靠或充分机制。特别是,恶意或受损的缓存可能无法识别或遵守此指令,并且通信网络可能容易受到窃听。

于 2009-05-15T03:53:01.483 回答
13

no-store在正常情况下应该没有必要,并且会损害速度和可用性。它适用于 HTTP 响应包含非常敏感的信息,因此根本不应该将其写入磁盘缓存,无论对用户产生的负面影响如何。

这个怎么运作:

  • 通常,即使浏览器等用户代理确定不应缓存响应,由于用户代理内部的原因,它仍可能将其存储到磁盘缓存中。此版本可用于“查看源代码”、“返回”、“页面信息”等功能,其中用户不一定再次请求该页面,但浏览器不会将其视为新页面视图并且提供用户当前正在查看的相同版本是有意义的。

  • 使用no-store将阻止该响应被存储,但这可能会影响浏览器提供“查看源代码”、“返回”、“页面信息”等的能力,而无需向服务器发出新的、单独的请求,这是不可取的。换句话说,用户可能会尝试查看源代码,如果浏览器没有将其保存在内存中,他们要么会被告知这是不可能的,要么会导致对服务器的新请求。因此,no-store仅当这些功能无法正常或快速运行的受阻用户体验被确保内容不存储在缓存中的重要性超过时才应使用。

我目前的理解是它仅适用于中间缓存服务器。即使响应“无缓存”,中间缓存服务器仍然可以将内容保存到非易失性存储中。

这是不正确的。与 HTTP 1.1 兼容的中间缓存服务器将遵循no-cachemust-revalidate指令,确保内容不被缓存。使用这些指令将确保响应不会被任何中间缓存缓存,并且所有后续请求都将发送回源服务器。

如果中间缓存服务器不支持 HTTP 1.1,那么您将需要使用Pragma: no-cache并希望获得最好的结果。请注意,如果它不支持 HTTP 1.1,那么no-store无论如何都无关紧要。

于 2009-05-15T05:20:48.777 回答
12

如果您想阻止所有缓存(例如,使用后退按钮时强制重新加载),您需要:

  • IE 无缓存

  • Firefox 没有商店

这里有我的相关信息:

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

于 2009-05-15T09:50:41.187 回答
9

如果缓存系统正确实现了无存储,那么您就不需要无缓存。但并非所有人都这样做。此外,一些浏览器实现了 no-cache ,就像它是 no-store 一样。因此,虽然不是严格要求,但将两者都包括在内可能是最安全的。

于 2012-01-03T15:24:26.140 回答
8

对于 chrome,no-cache 用于在重新访问时重新加载页面,但如果您返回历史记录(后退按钮),它仍然会缓存它。要重新加载页面以返回历史记录,请使用 no-store。IE 需要重新验证才能在所有场合下工作。

所以只是为了确保避免我一直使用的所有错误和误解

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

如果我想确保它重新加载。

于 2013-10-28T11:30:37.520 回答
6

请注意,从版本 5 到 8 的 Internet Explorer 在尝试下载通过 https 提供的文件和服务器发送Cache-Control: no-cachePragma: no-cache标头时会引发错误。

请参阅http://support.microsoft.com/kb/812935/en-us

使用Cache-Control: no-storeandPragma: private似乎是最接近仍然有效的东西。

于 2013-06-24T13:07:01.673 回答
3

最初我们在多年前使用 no-cache 并且确实在某些浏览器上遇到了一些陈旧内容的问题......不幸的是,不记得具体细节。

从那以后,我们决定只使用无商店。从那以后,任何浏览器或中介都没有回头或遇到过任何过时内容的问题。

这个空间肯定是由实现的现实与碰巧在各种 RFC 中编写的内容所主导。尤其是许多代理人倾向于认为通过用自己的政策取代他们应该遵循的政策,他们在“提高绩效”方面做得更好。

于 2009-05-15T04:55:39.757 回答
1

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

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

于 2009-08-02T10:16:25.733 回答
0

为了回答这个问题,这里有两个参与者,客户端(请求)和服务器(响应)。

客户:

客户端只能使用一种缓存方法进行请求。有不同的方法,如果没有指定,将使用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. 如果没有缓存:抛出网络错误。

笔记:

  • 仍然“有效”意味着电流agestale-while-revalidate生命周期内。它需要“重新验证”,但仍然可以退货。
  • 这里的“Fetch”,为简单起见,是“non-conditional network fetch”的缩写。
  • “带条件获取”意味着使用诸如 的标头进行获取 If-Modified-Since,或者ETag服务器可以使用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会覆盖所有内容。是的,您可能已经同时看到了两者,并且在损坏的浏览器实现之外它是无用的。尽管如此,no-store自 1999 年以来一直是规范的一部分:https ://datatracker.ietf.org/doc/html/rfc2616#section-14.9.2

在实际使用中,如果您的服务器支持304: Not Modified,并且您想使用客户端缓存作为提高速度的一种方式,但仍想强制网络获取,请使用no-cache. 如果不支持304,并且想要强制网络获取,请使用no-store. 如果您有时可以使用缓存,请使用新鲜度和重新验证标头。

实际上,如果您在客户端上混在一起no-cacheno-store几乎不会发生任何变化。然后,只发送几个标头,浏览器将处理不同的内部响应。no-cache如果您使用然后忘记使用它,则可能会出现问题。no-cache告诉它将响应存储在缓存中,以后没有它的请求可能会触发内部缓存。

有时您可能希望根据上下文在同一资源上混合方法。例如,您可能希望reload在服务工作者和后台同步上使用,但default用于网页本身。这是您可以根据自己的喜好操作用户代理(浏览器)缓存的地方。请记住,服务器通常对缓存的工作方式拥有最终决定权。


澄清一些可能的未来混淆。客户端可以使用请求Cache-Control,告诉服务器在响应时不要使用自己的缓存系统。这与浏览器/服务器动态无关,更多关于服务器/数据库动态。

技术上也no-store意味着不得存储到任何非易失性存储(磁盘)并尽快从易失性存储(内存)中释放它。实际上,这意味着根本不使用缓存。该命令实际上是双向的。客户端请求no-store不应写入磁盘或数据库,并且是暂时的。


TL;DR:no-store覆盖no-cache. 两者都设置是没有用的,除非我们谈论的是不支持的或不支持的 HTTP/1.0 浏览器no-store(也许是 IE11?)。用于no-cache支持304

于 2022-02-01T17:22:40.067 回答
-1

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" ' 属性。然而,

来源在这里

于 2019-01-23T10:43:06.363 回答