本页概述了设置 Referrer-Policy 和在传入请求中使用引荐来源的一些最佳实践。
摘要
- 意外的跨源信息泄露会损害 Web 用户的隐私。采用保护性引荐来源网址政策可以帮助您解决此问题。
- 考虑将引荐来源网址政策设置为
strict-origin-when-cross-origin
。它保留了大部分引荐来源的实用性,同时降低了跨源数据泄露的风险。 - 请勿使用引荐来源来防范跨站请求伪造 (CSRF)。请改用 CSRF 令牌,并使用其他标头作为额外的安全层。
引荐来源网址和 Referrer-Policy 基础知识
HTTP 请求可包含一个可选的 Referer
标头,用于指示发出请求的来源或网页网址。Referrer-Policy
标头定义了 Referer
标头中提供哪些数据。
在以下示例中,Referer
标头包含 site-one
上发出请求的网页的完整网址。
Referer
标头可能出现在不同类型的请求中:
- 当用户点击链接时发出的导航请求。
- 子资源请求:当浏览器请求网页所需的图片、iframe、脚本和其他资源时。
对于导航和 iframe,您还可以使用 document.referrer
通过 JavaScript 访问这些数据。
您可以从 Referer
值中了解很多信息。例如,分析服务可能会使用这些信息来确定 site-two.example
上 50% 的访问者来自 social-network.example
。但是,如果在 Referer
跨源中发送包含路径和查询字符串的完整网址,则可能会危害用户隐私并造成安全风险:
网址 1 到 5 包含私密信息,有时还包含敏感信息或身份信息。在多个来源之间静默泄露这些信息可能会侵犯网络用户的隐私。
网址 6 是 capability 网址。如果预期用户以外的任何人收到此类消息,恶意操作者就可以控制此用户的账号。
如需限制为来自您网站的请求提供哪些引荐来源数据,您可以设置引荐来源政策。
有哪些政策可用?它们之间有何不同?
您可以从以下八种政策中选择一种。根据政策,Referer
标头(和 document.referrer
)中的可用数据可以是:
- 无数据(不存在
Referer
标头) - 仅限来源
- 完整网址:源、路径和查询字符串
某些政策会设计为根据上下文表现出不同的行为:跨源请求或同源请求、请求目标页面是否像源站一样安全,或两者兼而有之。这有助于限制跨源或向安全性较低的源共享的信息量,同时保持您网站中引荐来源的丰富性。
下表显示了引荐来源政策如何限制通过引荐来源标头和 document.referrer
提供的网址数据:
政策范围 | 政策名称 | 引荐来源网址:无数据 | 引荐来源:仅限来源 | 引荐来源网址:完整网址 |
---|---|---|---|---|
不考虑请求上下文 | no-referrer |
检查 | ||
origin |
检查 | |||
unsafe-url |
检查 | |||
注重安全 | strict-origin |
将请求从 HTTPS 改为 HTTP | 从 HTTPS 到 HTTPS 或从 HTTP 到 HTTP 的请求 |
|
no-referrer-when-downgrade |
将请求从 HTTPS 改为 HTTP | 从 HTTPS 到 HTTPS 或 HTTP 到 HTTP 的请求 |
||
注重隐私保护 | origin-when-cross-origin |
跨源请求 | 同源请求 | |
same-origin |
跨源请求 | 同源请求 | ||
注重隐私和安全 | strict-origin-when-cross-origin |
从 HTTPS 到 HTTP 的请求 | 从 HTTPS 到 HTTPS 或 HTTP 到 HTTP 的跨源请求 |
同源请求 |
MDN 提供了政策和行为示例的完整列表。
以下是设置引荐来源网址政策时需要注意的事项:
- 所有考虑架构(HTTPS 与 HTTP)的政策(
strict-origin
、no-referrer-when-downgrade
和strict-origin-when-cross-origin
)都会将从一个 HTTP 源到另一个 HTTP 源的请求与从一个 HTTPS 源到另一个 HTTPS 源的请求视为同等,即使 HTTP 的安全性较低也是如此。这是因为,对于这些政策,重要的是是否发生了安全降级;也就是说,请求是否会将加密来源的数据泄露到未加密来源,如 HTTPS → HTTP 请求。HTTP → HTTP 请求完全未加密,因此不会降级。 - 如果请求是同源请求,则表示架构(HTTPS 或 HTTP)相同,因此不会降低安全级别。
浏览器中的默认引荐来源网址政策
自 2021 年 10 月起
如果未设置引荐来源网址政策,浏览器将使用其默认政策。
浏览器 | 默认 Referrer-Policy /行为 |
---|---|
Chrome |
默认为 strict-origin-when-cross-origin 。
|
Firefox |
默认值为 strict-origin-when-cross-origin 。从版本 93 开始,对于“严格跟踪保护”功能和“无痕浏览”用户,跨网站请求会忽略较为宽松的引荐来源网址政策 no-referrer-when-downgrade 、origin-when-cross-origin 和 unsafe-url ,这意味着系统会始终针对跨网站请求调整引荐来源网址,而不考虑网站的政策。
|
Edge |
默认为 strict-origin-when-cross-origin 。
|
Safari |
默认值类似于 strict-origin-when-cross-origin ,但有一些特定区别。如需了解详情,请参阅
阻止跟踪防范跟踪。
|
设置引荐来源政策的最佳实践
您可以通过多种方式为您的网站设置引荐来源政策:
您可以为不同的页面、请求或元素设置不同的政策。
HTTP 标头和 meta 元素都是网页级的。确定元素有效政策的优先级顺序如下:
- 元素级政策
- 网页级政策
- 浏览器默认设置
示例:
index.html
:
<meta name="referrer" content="strict-origin-when-cross-origin" />
<img src="..." referrerpolicy="no-referrer-when-downgrade" />
使用 no-referrer-when-downgrade
政策请求映像,此页面中的所有其他子资源请求均遵循 strict-origin-when-cross-origin
政策。
如何查看引荐来源政策?
您可以使用 securityheaders.com 轻松确定特定网站或网页使用的是哪项政策。
您还可以使用 Chrome、Edge 或 Firefox 中的开发者工具查看针对特定请求使用的引荐来源政策。在撰写本文时,Safari 不显示 Referrer-Policy
标头,但会显示发送的 Referer
。
您应为自己的网站设置哪些政策?
我们强烈建议您明确设置可增强隐私保护的政策,例如 strict-origin-when-cross-origin
(或更严格的政策)。
为什么要使用“明确”一词?
如果您未设置引荐来源网址政策,系统将使用浏览器的默认政策。事实上,网站通常会遵循浏览器的默认政策。但这并不理想,因为:
- 不同浏览器的默认政策各不相同,因此,如果您依赖浏览器默认设置,您的网站在不同浏览器中的行为将无法预测。
- 浏览器采用更严格的默认值(例如
strict-origin-when-cross-origin
)和机制(例如针对跨源请求的引荐来源网址剪辑)。在浏览器默认设置发生变化之前明确选择启用可增强隐私保护的政策,可让您掌控一切并根据需要运行测试。
为什么是 strict-origin-when-cross-origin
(或更严格)?
您需要制定安全、注重隐私保护且实用的政策。“有用”的含义取决于您希望从引荐来源获得什么:
- 安全:如果您的网站使用 HTTPS(如果没有,请优先考虑),则不希望网站的网址在非 HTTPS 请求中泄露。由于网络上的任何人都可以看到这些信息,因此如果发生泄露,您的用户将面临中间人攻击。
no-referrer-when-downgrade
、strict-origin-when-cross-origin
、no-referrer
和strict-origin
政策可解决此问题。 - 增强隐私保护:对于跨源请求,
no-referrer-when-downgrade
会共享完整网址,这可能会导致隐私问题。strict-origin-when-cross-origin
和strict-origin
仅共享起源,no-referrer
则完全不共享。这样一来,您就可以使用strict-origin-when-cross-origin
、strict-origin
和no-referrer
来增强隐私保护。 - 有用:
no-referrer
和strict-origin
绝不会共享完整网址,即使对于同源请求也是如此。如果您需要完整网址,strict-origin-when-cross-origin
是更好的选择。
所有这些都意味着,strict-origin-when-cross-origin
通常是一个明智的选择。
示例:设置 strict-origin-when-cross-origin
政策
index.html
:
<meta name="referrer" content="strict-origin-when-cross-origin" />
或者在服务器端(例如在 Express 中):
const helmet = require('helmet');
app.use(helmet.referrerPolicy({policy: 'strict-origin-when-cross-origin'}));
如果 strict-origin-when-cross-origin
(或更严格的权限)无法满足您的所有用例,该怎么办?
在这种情况下,请采用渐进式方法:为您的网站设置 strict-origin-when-cross-origin
等保护性政策,并根据需要为特定请求或 HTML 元素设置更宽松的政策。
示例:元素级政策
index.html
:
<head>
<!-- document-level policy: strict-origin-when-cross-origin -->
<meta name="referrer" content="strict-origin-when-cross-origin" />
<head>
<body>
<!-- policy on this <a> element: no-referrer-when-downgrade -->
<a src="…" href="…" referrerpolicy="no-referrer-when-downgrade"></a>
<body></body>
</body>
</head>
</head>
Safari/WebKit 可能会对跨网站请求的 document.referrer
或 Referer
标头设置上限。查看详情。
示例:请求级政策
script.js
:
fetch(url, {referrerPolicy: 'no-referrer-when-downgrade'});
您还应考虑哪些事项?
您的政策应取决于您的网站和用例,由您、您的团队和贵公司确定。如果某些网址包含身份信息或敏感数据,请设置保护政策。
传入请求的最佳做法
以下是一些指南,说明如果您的网站使用传入请求的引荐来源网址,应采取哪些措施。
保护用户数据
Referer
可能包含私密数据、个人数据或身份数据,因此请务必将其视为此类数据。
传入的引荐来源网址可能会发生变化 {referer-can-change}
使用传入的跨源请求中的引荐来源网址会有一些限制:
- 如果您无法控制请求发射器的实现,则无法对您收到的
Referer
标头(和document.referrer
)做出假设。请求发出器可能会随时决定改用no-referrer
政策,或者改用比之前更严格的政策。这意味着,您从Referer
收到的数据比以前要少。 - 越来越多的浏览器默认使用 Referrer-Policy
strict-origin-when-cross-origin
。这意味着,如果发送方网站未设置政策,您现在在收到的跨源请求中可能只会收到来源,而不是完整的引荐来源网址。 - 浏览器可能会更改
Referer
的管理方式。例如,某些浏览器开发者可能会决定始终在跨源子资源请求中修剪指向来源的引荐来源,以保护用户隐私。 Referer
标头(和document.referrer
)可能包含的数据量超出了您的需求。例如,如果您只想知道请求是否跨源,则可以使用完整网址。
Referer
的替代方案
在以下情况下,您可能需要考虑替代方案:
- 您网站的一项重要功能使用传入跨源请求的引荐来源网址。
- 您的网站不再在跨源请求中收到所需的引荐来源网址的部分。如果请求发射器更改了其政策,或者未设置政策且浏览器默认政策发生了变化(例如在 Chrome 85 中),就会发生这种情况。
要定义替代方法,请先分析您使用的引荐来源网址的哪一部分。
如果您只需要
- 如果您在对网页具有顶级访问权限的脚本中使用了引荐来源,则可以改用
window.location.origin
。 Origin
和Sec-Fetch-Site
等标头可为您提供Origin
或说明请求是否为跨源请求(可能正是您需要的)。
如果您需要网址的其他元素(路径、查询参数...)
- 请求参数可能会解决您的用例,从而为您节省解析引荐来源的工作。
- 如果您在对网页具有顶级访问权限的脚本中使用引荐来源网址,可以使用
window.location.pathname
作为替代方案。仅提取网址的路径部分,并将其作为参数传递,以免传递网址参数中的任何可能敏感的信息。
如果您无法使用这些替代方案,请执行以下操作:
- 检查您是否可以更改系统,以便请求发射器(例如
site-one.example
)在某种配置中明确设置您需要的信息。- 优点:更明确,可更好地保护
site-one.example
用户的隐私,更具前瞻性。 - 缺点:您或系统用户可能需要执行更多工作。
- 优点:更明确,可更好地保护
- 检查发出请求的网站是否可能同意设置每个元素或每个请求的 Referrer-Policy 为
no-referrer-when-downgrade
。- 缺点:对
site-one.example
用户的隐私保护力度可能较低,可能并非所有浏览器都支持此功能。
- 缺点:对
跨站请求伪造 (CSRF) 防范
请求发送方可以随时通过设置 no-referrer
政策来决定不发送引荐来源,而恶意行为者甚至可以伪造引荐来源。
将 CSRF 令牌用作您的主要保护措施。为了提供额外的保护,请使用 SameSite(而非 Referer
),使用 Origin
(适用于 POST 和 CORS 请求)和 Sec-Fetch-Site
(如果有)等标头。
日志记录和调试
请务必保护可能位于 Referer
中的用户个人数据或敏感数据。
如果您只使用来源,请检查是否可以使用 Origin
标头作为替代方案。这样,您或许可以更简单地获取调试所需的信息,而无需解析引荐来源。
付款
付款服务提供商可能会依赖传入请求的 Referer
标头进行安全检查。
例如:
- 用户点击
online-shop.example/cart/checkout
上的购买按钮。 online-shop.example
重定向到payment-provider.example
以管理交易。payment-provider.example
会根据商家设置的一系列允许的Referer
值检查此请求的Referer
。如果不匹配列表中的任何条目,payment-provider.example
会拒绝请求。如果匹配,用户可以继续进行交易。
付款流程安全检查的最佳做法
作为付款服务提供商,您可以使用 Referer
作为基本检查来防范某些攻击。不过,仅凭 Referer
标头并不足以进行检查。无论是合法商家还是其他网站,发出请求的网站都可以设置 no-referrer
政策,使付款服务提供商无法获取 Referer
信息。
查看 Referer
可能会帮助付款服务提供商抓住未设置 no-referrer
政策的无知攻击者。如果您使用 Referer
作为第一项检查,请执行以下操作:
- 不要假设
Referer
始终存在。如果存在,请仅与其可以包含的最少数据(即来源)进行对比。- 在设置允许的
Referer
值列表时,请确保仅包含出发地,而不包含路径。 - 例如,
online-shop.example
允许的Referer
值应该是online-shop.example
,而不是online-shop.example/cart/checkout
。通过预期任何Referer
值或Referer
值仅为发出请求的网站的来源,您可以避免因假设商家的Referrer-Policy
而导致的错误。
- 在设置允许的
- 如果没有
Referer
,或者存在Referer
且基本Referer
来源检查成功,您可以改用其他更可靠的验证方法。
为了更可靠地验证付款,请让请求方对请求参数进行哈希处理,并附上唯一键。然后,付款服务提供商可以在您这边计算相同的哈希值,并且仅在请求与您的计算结果一致时接受该请求。
当没有引荐来源政策的 HTTP 商家网站重定向到 HTTPS 付款服务提供商时,Referer
会怎样?
向 HTTPS 付款服务机构发送的请求中不会显示任何 Referer
,因为如果网站未设置政策,大多数浏览器会默认使用 strict-origin-when-cross-origin
或 no-referrer-when-downgrade
。Chrome 对新默认政策的更改不会改变此行为。
总结
保护性引荐来源网址政策是为用户提供更多隐私保护的好方法。
如需详细了解保护用户的各种不同方法,请参阅我们的安全集合
资源
- 了解“同网站”和“同源”
- 新的安全标头:引荐来源政策 (2017)
- MDN 上的引荐来源网址政策
- 引荐来源网址:MDN 的隐私和安全问题
- Chrome 变更:要实现的 Blink intent
- Chrome 变更:Blink intent 将发布
- Chrome 变更:状态条目
- “Chrome 变更:85 Beta 版”博文
- 引荐来源网址修剪 GitHub 线程:不同浏览器执行的操作
- Referrer-Policy 规范
非常感谢所有审核者(尤其是 Kaustubha Govind、David Van Cleve、Mike West、Sam Dutton、Rowan Merewood、Jxck 和 Kayce Basques)提供的贡献和反馈。