1. 简介
本节为非规范性内容。
从文档发出的请求以及从该文档导航离开的请求都与 Referer
头相关联。虽然可以通过带有 noreferrer
链接类型的链接抑制该头,但作者可能希望出于多种原因更直接地控制 Referer
头:
1.1. 隐私
一个社交网站为其用户提供个人资料页面,用户可以在个人资料页面上添加指向他们喜欢的乐队的超链接。当其他用户点击这些超链接时,社交网站可能不希望将用户的个人资料 URL 泄露给乐队网站(因为个人资料 URL 可能会暴露个人资料所有者的身份)。
然而,一些社交网站可能希望通知乐队网站这些链接来自社交网站,但不透露具体是哪个用户的个人资料包含这些链接。
1.2. 安全
一个使用 HTTPS 和基于 URL 的会话标识符的 Web 应用可能希望链接到其他网站上的 HTTPS 资源,而不泄露用户的会话标识符。
或者,一个 Web 应用可能使用 URL 本身授予某些能力。控制引用可以帮助防止这些能力 URL 通过引用头泄露。[CAPABILITY-URLS]
请注意,能力 URL 可能通过其他方式泄露,控制引用不足以控制所有这些潜在泄露。
1.3. 回溯
一个通过 HTTPS 托管的博客可能希望链接到一个通过 HTTP 托管的博客并接收回溯链接。
2. 关键概念和术语
3. 引用策略
一个 引用策略
可以是空字符串、"no-referrer
"、"no-referrer-when-downgrade
"、"same-origin
"、"origin
"、"strict-origin
"、"origin-when-cross-origin
"、"strict-origin-when-cross-origin
"
或 "unsafe-url
"。
enum ReferrerPolicy {
"",
"no-referrer",
"no-referrer-when-downgrade",
"same-origin",
"origin",
"strict-origin",
"origin-when-cross-origin",
"strict-origin-when-cross-origin",
"unsafe-url"
};
每种可能的 引用策略 在下文中进行了说明。评估其效果的详细算法在 §5 与 Fetch 的集成 和 §8 算法 部分中给出。
注意:环境设置对象
的引用策略为请求提供了默认的基线策略,当该 环境设置对象
用作 请求客户端
时使用。此策略可以通过诸如
noreferrer
链接类型的机制为特定请求收紧。
3.1. "no-referrer
"
最简单的策略是 "no-referrer
",它指定不应将任何引用信息与从特定 请求客户端
发出的请求一起发送到任何 来源。头将完全省略。
https://example.com/page.html
的文档设置了 "no-referrer
" 策略,则导航到
https://example.com/
(或任何其他 URL)将不会发送 Referer
头。
3.2. "no-referrer-when-downgrade
"
"no-referrer-when-downgrade
"
策略会将完整的 URL 与从 TLS 保护的 环境设置对象
发出的请求一起发送到 潜在可信 URL,以及从
客户端(未
TLS
保护)发出的请求发送到任何 来源。
从 TLS 保护的
客户端 发出的请求到非 潜在可信
URL,则不会包含任何引用信息。不会发送
Referer
HTTP 头。
https://example.com/page.html
的文档设置了 "no-referrer-when-downgrade
"
策略,则导航到 https://not.example.com/
会发送一个
Referer
HTTP 头,其值为 https://example.com/page.html
,因为两个资源的来源都不是非 潜在可信 URL。
从同一页面导航到 http://not.example.com/
则不会发送 Referer
头。
如果未指定其他策略,这是用户代理的默认行为。
3.3. "same-origin
"
"same-origin
" 策略指定,当从特定 客户端 发出 同源请求
时,会发送一个完整的 URL(剥离以用作引用)作为引用信息。
跨源请求,另一方面,不会包含任何引用信息。不会发送
Referer
HTTP 头。
https://example.com/page.html
的文档设置了 "same-origin
" 策略,则导航到
https://example.com/not-page.html
会发送一个 Referer
头,其值为
https://example.com/page.html
。
从同一页面导航到 https://not.example.com/
则不会发送 Referer
头。
3.4. "origin
"
"origin
" 策略指定,仅发送 ASCII 序列化 的 来源作为引用信息,无论是从特定 客户端 发出的 同源请求 还是 跨源请求。
注意:来源的序列化看起来像 https://example.com
。为了确保在 `Referer
` 头中发送有效的 URL,用户代理会在来源后附加一个
U+002F SOLIDUS ("/
") 字符,例如 https://example.com/
。
注意:"origin
" 策略会导致 HTTPS 引用的来源作为未加密 HTTP
请求的一部分通过网络发送。"strict-origin
" 策略解决了这一问题。
https://example.com/page.html
的文档设置了 "origin
" 策略,则导航到任何 来源都会发送一个 Referer
头,其值为
https://example.com/
,即使 URL 不是 潜在可信 URL。
3.5.
"strict-origin
"
"strict-origin
" 策略在发出请求时发送 ASCII 序列化 的 来源:
从 TLS 保护的
请求客户端 发出的请求到非
潜在可信
URL,不会包含任何引用信息。不会发送
Referer
HTTP 头。
https://example.com/page.html
的文档设置了 "strict-origin
" 策略,则导航到
https://not.example.com
会发送一个 Referer
头,其值为
https://example.com/
。
从同一页面导航到 http://not.example.com
则不会发送 Referer
头。
http://example.com/page.html
的文档设置了
"strict-origin
" 策略,则导航到
http://not.example.com
或 https://example.com
会发送一个 Referer
头,其值为
http://example.com/
。
3.6. "origin-when-cross-origin
"
"origin-when-cross-origin
"
策略指定,当从特定 请求客户端
发出 同源请求
时,会发送一个完整的 URL(剥离以用作引用)作为引用信息;而当发出 跨源请求 时,仅发送 ASCII 序列化 的 来源。
注意:对于 "origin-when-cross-origin
"
策略,我们还将协议升级(例如从 http://example.com/
到 https://example.com/
的请求)视为 跨源请求。
注意:"origin-when-cross-origin
"
策略会导致 HTTPS 引用的来源作为未加密 HTTP 请求的一部分通过网络发送。"strict-origin-when-cross-origin
"
策略解决了这一问题。
https://example.com/page.html
的文档设置了 "origin-when-cross-origin
"
策略,则导航到 https://example.com/not-page.html
会发送一个 Referer
头,其值为
https://example.com/page.html
。
从同一页面导航到 https://not.example.com/
会发送一个 Referer
头,其值为
https://example.com/
,即使 URL 不是 潜在可信
URL。
3.7. "strict-origin-when-cross-origin
"
"strict-origin-when-cross-origin
"
策略指定,当从特定 请求客户端
发出 同源请求
时,会发送一个完整的 URL(剥离以用作引用)作为引用信息;而当发出 跨源请求 时,仅发送 ASCII 序列化 的 来源:
从 TLS 保护的
客户端 发出的请求到非 潜在可信
URL,不会包含任何引用信息。不会发送
Referer
HTTP 头。
https://example.com/page.html
的文档设置了 "strict-origin-when-cross-origin
"
策略,则导航到 https://example.com/not-page.html
会发送一个 Referer
头,其值为
https://example.com/page.html
。
从同一页面导航到 https://not.example.com/
会发送一个 Referer
头,其值为
https://example.com/
。
从同一页面导航到 http://not.example.com/
则不会发送 Referer
头。
3.8. "unsafe-url
"
"unsafe-url
" 策略指定,无论是从特定 客户端 发出的 同源请求 还是 跨源请求,都会发送一个完整的 URL(剥离以用作引用)作为引用信息。
https://example.com/sekrit.html
的文档设置了 "unsafe-url
" 策略,则导航到
http://not.example.com/
(以及其他所有来源)会发送一个
Referer
HTTP 头,其值为 https://example.com/sekrit.html
。
注意:该策略的名称并未误导;它确实不安全。此策略会将 TLS 保护资源的来源和路径泄露到不安全的来源。请仔细考虑为潜在敏感文档设置此类策略的影响。
3.9. 空字符串
空字符串 "" 对应于没有 引用策略,导致回退到其他地方定义的 引用策略,或者在没有此类高级策略的情况下,默认回退到 "no-referrer-when-downgrade
"。此默认行为发生在
§8.3
确定请求的引用 算法中。
a
元素,没有声明任何
referrerpolicy
属性,其引用策略为空字符串。因此,通过点击该
a
元素发起的导航请求将使用该
a
元素的 引用策略。如果该
Document
的引用策略为空字符串,则 §8.3
确定请求的引用 算法会将空字符串视为 "no-referrer-when-downgrade
"。
4. 引用策略的传递
- 通过
Referrer-Policy
HTTP 头(定义在 §4.1 通过 Referrer-Policy 头传递)。 - 通过
meta
元素,其name
属性为referrer
。 - 通过
referrerpolicy
内容属性,应用于以下元素:a
、area
、img
、iframe
或link
。 - 通过
noreferrer
链接关系,应用于以下元素:a
、area
或link
。 - 通过继承隐式传递。
4.1. 通过 Referrer-Policy 头传递
Referrer-Policy
HTTP 头指定了用户代理在确定应包含哪些引用信息时应用的引用策略,以及在从受保护资源的上下文创建的 浏览上下文中应用的策略。头名称和值的语法由以下
ABNF 语法描述:
"Referrer-Policy:" 1#policy-token
policy-token = "no-referrer" / "no-referrer-when-downgrade" / "strict-origin" / "strict-origin-when-cross-origin" / "same-origin" / "origin" / "origin-when-cross-origin" / "unsafe-url"
注意:头名称与 HTTP Referer 头的拼写错误无关。
§5 与 Fetch 的集成 和 §6 与 HTML
的集成 描述了如何处理 Referrer-Policy
头。
4.1.1. 使用
本节为非规范性内容。
受保护资源可以通过将 no-referrer
指定为其 Referrer-Policy
头的值来防止引用泄漏:
Referrer-Policy: no-referrer
这将导致从受保护资源的上下文发出的所有请求都具有空的 Referer
[sic] 头。
4.2.
通过
meta
传递
本节为非规范性内容。
4.3. 通过 referrerpolicy
内容属性传递
本节为非规范性内容。
HTML 标准定义了 引用策略属性 的概念,适用于其多个元素,例如:
<a href="http://example.com" referrerpolicy="origin">
4.4. 嵌套浏览上下文
本节为非规范性内容。
HTML 标准和 Fetch 标准定义了如何处理嵌套浏览上下文,这些上下文不是从 响应 创建的,例如设置了
iframe
元素的
srcdoc
属性,或从 blob URL 创建的上下文。这些上下文会从创建它们的浏览上下文或 blob URL 继承其 引用策略。
5. 与 Fetch 的集成
本节为非规范性内容。
Fetch 规范在 §8.2 设置请求的引用策略(重定向) 中调用,在 HTTP 重定向 Fetch 的第 13 步之前,以便在跟随重定向之前更新请求的引用策略。
Fetch 规范在 §8.3
确定请求的引用 中调用,作为 主 Fetch 算法的第 8 步,并使用结果设置
request 的 referrer
属性。Fetch 负责序列化提供的 URL,并在 request 上设置
`Referer
` 头。
6. 与 HTML 的集成
本节为非规范性内容。
HTML 标准确定了在 导航或 运行 worker 时接收到的任何响应的 引用策略,并使用结果设置生成的
Document
或 WorkerGlobalScope
的引用策略。随后,这些策略由相应的 环境设置对象使用,该对象作为
请求客户端,用于其发起的 Fetch。
注意:W3C HTML5 未定义 referrerpolicy
内容属性、referrerPolicy
IDL 属性、referrer
关键字(用于
meta
),或与导航或运行
worker 的集成。为了使本规范与 W3C HTML5 一致,需要从 [HTML] 中复制这些内容。
7. 与 CSS 的集成
CSS 标准未指定如何获取样式表引用的资源。然而,实施应确保设置样式表发起的任何 请求 的引用相关属性,如下所示:
- 如果请求由 CSS 声明块负责,则将 引用 设置为块的 所有者节点的 节点文档的 URL,并将 引用策略 设置为块的 所有者节点的 节点文档的 引用策略。
-
如果请求由 CSS
样式表负责,并且其 位置 非空,则将 引用 设置为其
位置,并将 引用策略 设置为其 引用策略。
这要求 CSS 样式表处理 `Referrer-Policy` 头,并以与 文档相同的方式存储 引用策略。
- 否则,由 CSS 样式表负责的请求,其 位置 为 null:将 引用 设置为其 所有者节点的 节点文档的 URL,并将 引用策略 设置为块的 所有者节点的 节点文档的 引用策略。
注意:请求的 引用 和 引用策略 的值是基于创建请求时的值设置的。如果文档的引用策略在其生命周期内发生变化,与内联样式表请求相关联的策略也会随之变化。
8. 算法
8.1.
从 Referrer-Policy
头解析引用策略
给定一个 Response
response,以下步骤根据 response 的 `Referrer-Policy
` 头返回一个 引用策略:
- 让 policy-tokens 是 解析 response 的 头列表
中 `
Referrer-Policy
` 的结果。 - 让 policy 是空字符串。
- 对于 policy-tokens 中的每个 token,如果 token 是一个 引用策略 且 token 不是空字符串,则将
policy 设置为 token。
注意:此算法循环处理多个策略值,以允许为旧的用户代理提供回退,同时部署新的策略值,如 §11.1 未知策略值 中所述。
- 返回 policy。
8.2. 在重定向时设置 request 的引用策略
给定一个 请求 request 和一个 响应 actualResponse,此算法根据 actualResponse 中的 Referrer-Policy 头(如果有)更新 request 的关联 引用策略。
- 让 policy 是在 actualResponse 上执行 §8.1 从 Referrer-Policy 头解析引用策略 的结果。
- 如果 policy 不是空字符串,则将 request 的关联引用策略设置为 policy。
8.3. 确定 request 的引用
给定一个 Request
request,我们可以通过检查与其关联的 引用策略
来确定要发送的正确引用信息,如以下步骤所述,这些步骤返回 no referrer
或一个 URL:
- 让 policy 是 request 的关联 引用策略。
- 让 environment 是 request 的 客户端。
- 根据 request 的 引用 执行以下操作:
注意:如果 request 的 引用 是 "
no-referrer
",Fetch 不会调用此算法。 - 让 referrerURL 是 剥离 referrerSource 以用作引用 的结果。
- 让 referrerOrigin 是 剥离 referrerSource 以用作引用 的结果,并将
仅来源标志
设置为true
。 - 根据 policy 的值执行以下语句:
- "
no-referrer
" - 返回
no referrer
- "
origin
" - 返回 referrerOrigin
- "
unsafe-url
" - 返回 referrerURL
- "
strict-origin
" - "
strict-origin-when-cross-origin
" - "
same-origin
" -
- 如果 request 是一个 同源请求,则返回 referrerURL。
- 否则,返回
no referrer
。
- "
origin-when-cross-origin
" -
- 如果 request 是一个 跨源请求,则返回 referrerOrigin。
- 否则,返回 referrerURL。
- "
no-referrer-when-downgrade
"
注意:Fetch 会确保 request 的 引用策略 在调用此算法之前不是空字符串。
- "
8.4. 剥离 url 以用作引用
在将 URL 作为 `Referer
` 头的值发送时,某些部分必须被剥离:URL 的片段、用户名和密码组件应在发送前剥离。此算法接受一个
仅来源标志
,默认值为
false
。如果设置为 true
,算法将额外移除 URL 的路径和查询组件,仅保留方案、主机和端口。
9. 隐私注意事项
9.1. 用户控制
本规范中的内容不应被解释为阻止用户代理提供选项以更改通过 `Referer
` 头发送的信息。例如,用户代理可以允许用户完全抑制引用头,无论页面上的活动 引用策略 是什么。
10. 安全注意事项
10.1. 信息泄露
引用策略中的 "origin
"、"origin-when-cross-origin
"
和 "unsafe-url
" 可能分别通过不安全的传输泄露安全站点的来源和 URL。
尽管如此,这三个策略仍包含在规范中,以降低站点采用安全传输的阻力。
希望确保不泄露比默认策略更多信息的作者应改用以下策略状态:"same-origin
"、"strict-origin
"、"strict-origin-when-cross-origin
"
或 "no-referrer
"。
10.2. 降级到较不严格的策略
规范不禁止降级到较不严格的策略,例如从 "no-referrer
" 降级到 "unsafe-url
"。
一方面,不清楚对于所有可能的策略对,哪个策略更严格:虽然 "no-referrer-when-downgrade
"
不会通过不安全的传输泄露任何信息,而 "origin
" 会,但后者在跨源导航中泄露的信息较少。
另一方面,允许设置较不严格的策略使作者能够定义安全的回退,如 §11.1 未知策略值 中所述。
11. 编写注意事项
11.1. 未知的策略值
如 §8.1 从 Referrer-Policy 头解析引用策略 和
meta
referrer
算法所述,未知的策略值将被忽略,当多个来源指定引用策略时,将使用最新的值。这使得部署新的策略值成为可能。
unsafe-url
" 策略。站点可以指定一个 "origin
" 策略,然后是一个 "unsafe-url
" 策略:较旧的用户代理将忽略未知的 "unsafe-url
" 值并使用 "origin
",而较新的用户代理将使用 "unsafe-url
",因为它是最后处理的。
然而,这种行为不适用于 referrerpolicy
属性。作者可以动态设置和获取 referrerpolicy
属性,以检测是否支持特定的策略值。
12. 致谢
本规范在很大程度上基于 Adam Barth 和 Jochen Eisinger 的 Meta referrer 文档。