假设 Web 服务器同时支持 HTTP 和 HTTPS。如果浏览器使用 HTTP GET 和 HTTPS GET 获取相同的 JavaScript,并且 JavaScript 是可缓存的,那么浏览器是否会缓存相同 JavaScript 的两个副本?
我要问的原因是,如果只缓存一个副本,攻击者是否有可能首先欺骗受害者通过 HTTP 下载 JavaScript 并一路破坏它,从而导致缓存中毒攻击?
假设 Web 服务器同时支持 HTTP 和 HTTPS。如果浏览器使用 HTTP GET 和 HTTPS GET 获取相同的 JavaScript,并且 JavaScript 是可缓存的,那么浏览器是否会缓存相同 JavaScript 的两个副本?
我要问的原因是,如果只缓存一个副本,攻击者是否有可能首先欺骗受害者通过 HTTP 下载 JavaScript 并一路破坏它,从而导致缓存中毒攻击?
资源由它们的 URL 缓存,协议 (http://
或https://
) 是 URL 的一部分。由于协议不同,因此 URL 也必须不同,并且您有两个单独的缓存条目。
http://
如果一个和一个https://
资源提供不同的数据,即使除了访问方法之外的所有内容都相同,那也很好。例如,http://
今天访问将经常导致重定向响应,同时访问以https://
提供真实内容。因此,浏览器将缓存这些资源,彼此独立。
概括:
http:
于所有不安全请求和https:
所有安全请求当前的 HTTP 标准分为多个“RFC”文档,其中RFC 7234完全专用于缓存,因为涉及很多复杂性。
在第 2 节“缓存操作概述”中,有这样的总结:
主缓存键由请求方法和目标 URI 组成。但是,由于当今常用的 HTTP 缓存通常仅限于缓存对 GET 的响应,因此许多缓存只是拒绝其他方法并仅使用 URI 作为主缓存键。
这在第 4 节的第一个要点中有更正式的说明,它说:
当出现请求时,缓存不得重用存储的响应,除非 [...] 提供的有效请求 URI(RFC7230 的第 5.5 节)与存储的响应匹配 [...]
RFC 7230的第 5.5 节开头说
对于用户代理,有效的请求 URI 是目标 URI。
浏览器是一个“用户代理”,所以我们在这里关心的就是这种情况。“目标 URI”在第 5.1 节中定义:
URI 引用(第 2.7 节)通常用作“目标资源”的标识符,用户代理会将其解析为其绝对形式以获得“目标 URI”。目标 URI 不包括引用的片段组件(如果有),因为片段标识符是为客户端处理保留的(RFC3986,第 3.5 节)。
URI 的通用定义在RFC 3986中,HTTP 特定的问题占据了 RFC 7230 的三页。与我们的目的最相关的部分是RFC 3986 第 4.1 节,它为绝对 URI 定义了这个语法:
absolute-URI = scheme ":" hier-part [ "?" 询问 ]
至关重要的是,请注意这scheme
是任何绝对 URI 的强制性部分。由于 HTTP URI 始终使用 schemehttp
而 HTTPS URI 始终使用 scheme https
,这意味着它们的绝对 URI 以及它们在浏览器中的“主缓存键”永远不会发生冲突。
其他答案提到了端口。RFC 7230,第 2.7.1 节将 URI定义http
为包括“权限”部分,该部分在 [RFC 3986,第 3.2 节]中定义:
权限= [用户信息“@”]主机[“:”端口]
该端口是可选的,RFC 7230 第 2.7.1 节定义了http
URI 方案的默认值:
如果端口子组件为空或未给出,则默认为 TCP 端口 80(为 WWW 服务保留的端口)。
以下部分定义了“https”的默认值:
上面列出的“http”方案的所有要求也是“https”方案的要求,除了如果端口子组件为空或未给出TCP端口443是默认的,并且......
然后是这样的:
因此,这些 URI 都将被单独缓存:
我唯一不清楚的是浏览器是否应该、可能或必须规范化明确提及默认端口的 URI。换句话说,这两个 URI 是否会被单独缓存:
我想不出将这些规范化为相同的缓存键的任何实际后果,因为根据上面的定义,它们保证代表相同的资源。
撇开规范非常清楚应该将不同的 URL 视为不同的资源这一事实不谈,如果不是这种情况,您不认为现在有人可能已经注意到并利用了这一点吗?在 cookie 暴露的所有问题(并由“安全”标志解决)已经知道 20 年或更长时间之后。
所以浏览器必须检索这两个 URL。可以想象,缓存可能会保留从不同来源下载但通过不同密钥访问的文件的单个副本 - 或者这种重复数据删除可能发生在文件系统的更深处(重复数据删除)。但这只会在缓存(或文件系统)确定文件相同之后发生。