本页概述了设置 Referrer-Policy 和在传入请求中使用引荐来源网址的一些最佳实践。
摘要
- 意外的跨源信息泄露会损害网络用户的隐私。保护性引荐来源网址政策可以提供帮助。
- 考虑将引荐来源网址政策设置为
strict-origin-when-cross-origin。它在保留引荐来源网址的大部分实用性的同时,降低了跨源泄露数据的风险。 - 不使用引荐来源网址进行跨站请求伪造 (CSRF) 保护。请改用 CSRF 令牌,并使用其他标头作为额外的安全层。
Referer 和 Referrer-Policy 基础知识
HTTP 请求可以包含可选的 Referer 标头,用于指明请求的来源或发出请求的网页网址。Referrer-Policy 标头用于定义 Referer 标头中提供的数据。
在以下示例中,Referer 标头包含发出请求的 site-one 上网页的完整网址。
Referer 标头可能会出现在不同类型的请求中:
- 导航请求,当用户点击链接时。
- 子资源请求,指浏览器请求网页所需的图片、iframe、脚本和其他资源。
对于导航和 iframe,您还可以使用 JavaScript 通过 document.referrer 访问此数据。
您可以从 Referer 值中了解很多信息。例如,分析服务可能会使用这些信息来确定 site-two.example 上 50% 的访问者来自 social-network.example。但如果通过 Referer 跨源发送包含路径和查询字符串的完整网址,则可能会危及用户隐私并带来安全风险:
网址 1 至 5 包含私密信息,有时还包含敏感信息或身份信息。在不同来源之间静默泄露这些信息可能会损害网络用户的隐私。
网址 6 是功能网址。如果预期用户以外的任何人收到此电子邮件,恶意方都可以控制该用户的账号。
如需限制可用于处理来自您网站的请求的引荐来源网址数据,您可以设置引荐来源网址政策。
有哪些政策可用,它们之间有何区别?
您可以选择八项政策中的一项。根据政策,Referer 标头(和 document.referrer)中提供的数据可以是:
- 无数据(不存在
Referer标头) - 仅限来源
- 完整网址:来源、路径和查询字符串
某些政策旨在根据上下文(跨源请求或同源请求、请求目标是否与来源一样安全,或两者兼而有之)以不同的方式运行。这有助于限制跨源或向安全性较低的来源共享的信息量,同时保持您自己网站内引荐来源网址的丰富性。
下表显示了引荐来源网址政策如何限制可从 Referer 标头和 document.referrer 获取的网址数据:
| 政策范围 | 政策名称 | 引荐来源网址:无数据 | Referer:仅限来源 | 引荐来源网址:完整网址 |
|---|---|---|---|---|
| 不考虑请求上下文 | no-referrer |
check | ||
origin |
check | |||
unsafe-url |
check | |||
| 注重安全性 | 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,并使用 Origin(适用于 POST 和 CORS 请求)和 Sec-Fetch-Site 等标头(如果可用),而不是 Referer。
记录日志和调试
请务必保护 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 改为采用新的默认政策不会改变此行为。
总结
使用保护性引荐来源网址政策是为用户提供更高隐私保护的好方法。
如需详细了解保护用户的各种技术,请参阅我们的安全保障合集
资源
- 了解“同网站”和“同源”
- 新的安全标头:Referrer-Policy (2017 年)
- MDN 上的 Referrer-Policy
- Referer 标头:MDN 上的隐私和安全问题
- Chrome 变更:Blink 意图实现
- Chrome 变更:Blink 打算发布
- Chrome 更改:状态条目
- Chrome 变更:85 Beta 版博文
- 引荐来源网址截断 GitHub 帖子:不同浏览器会执行哪些操作
- Referrer-Policy 规范
非常感谢所有评价者提供的贡献和反馈,尤其是 Kaustubha Govind、David Van Cleve、Mike West、Sam Dutton、Rowan Merewood、Jxck 和 Kayce Basques。