Referer 和 Referrer-Policy 最佳实践

本页面概述了设置 Referrer-Policy 和在传入请求中使用 referrer 的一些最佳实践。

总结

  • 意外的跨源信息泄漏会损害 Web 用户的隐私。保护性 referrer 政策可以提供帮助。
  • 考虑设置 strict-origin-when-cross-origin 的 referrer 政策。它在保留 referrer 大部分用处的同时,减轻了跨源泄漏数据的风险。
  • 请勿将 referrer 用于跨站请求伪造 (CSRF) 保护。请改用 CSRF 令牌,并将其他标头作为额外的安全层。

Referer 和 Referrer-Policy 101

HTTP 请求可以包含可选的 Referer 标头,该标头指示发出请求的源或网页 URL。Referrer-Policy 标头定义了 Referer 标头中提供的数据。

在以下示例中,Referer 标头包含从 site-one 发出请求的页面的完整 URL。

HTTP request including a Referer header.
带有 Referer 标头的 HTTP 请求。

Referer 标头可能存在于不同类型的请求中

  • 导航请求,即用户点击链接时。
  • 子资源请求,即浏览器请求页面所需的图像、iframe、脚本和其他资源时。

对于导航和 iframe,您还可以使用 JavaScript 通过 document.referrer 访问此数据。

您可以从 Referer 值中了解很多信息。例如,分析服务可能会使用它们来确定 site-two.example 上 50% 的访问者来自 social-network.example。但是,当完整 URL(包括路径和查询字符串)在 跨源Referer 中发送时,可能会危及用户隐私并造成安全风险

URLs with paths, mapped to different privacy and security risks.
使用完整 URL 可能会影响用户隐私和安全。

URL #1 到 #5 包含私人信息,有时还包含敏感或可识别身份的信息。跨源静默泄漏这些信息可能会损害 Web 用户的隐私。

URL #6 是一个 能力 URL。如果预期用户以外的任何人收到此 URL,恶意行为者可能会控制该用户的帐户。

要限制从您的站点发出的请求可用的 referrer 数据,您可以设置 referrer 政策。

有哪些政策可用?它们有何不同?

您可以选择八种政策之一。根据政策,Referer 标头(和 document.referrer)中提供的数据可以是

  • 无数据(不存在 Referer 标头)
  • 完整 URL:源、路径和查询字符串
Data that can
    be contained in the Referer header and document.referrer.
Referer 数据示例。

某些政策旨在根据上下文表现出不同的行为:跨源或同源请求,请求目标是否与源一样安全,或者两者兼而有之。这对于限制跨源或向不太安全的源共享的信息量很有用,同时在您自己的站点内保持 referrer 的丰富性。

下表显示了 referrer 政策如何限制 Referer 标头和 document.referrer 中可用的 URL 数据

政策范围 政策名称 Referer:无数据 Referer:仅源 Referer:完整 URL
不考虑请求上下文 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 提供了政策和行为示例的完整列表

以下是设置 referrer 政策时需要注意的一些事项

  • 所有考虑方案(HTTPS 与 HTTP)的政策(strict-originno-referrer-when-downgradestrict-origin-when-cross-origin)都将从一个 HTTP 源到另一个 HTTP 源的请求,与从 HTTPS 源到另一个 HTTPS 源的请求视为相同,即使 HTTP 的安全性较低。这是因为对于这些政策,重要的是是否发生安全降级;也就是说,请求是否可能将来自加密源的数据暴露给未加密源,例如 HTTPS → HTTP 请求。HTTP → HTTP 请求完全未加密,因此不存在降级。
  • 如果请求是同源的,则意味着方案(HTTPS 或 HTTP)相同,因此不存在安全降级。

浏览器中的默认 referrer 政策

截至 2021 年 10 月

如果未设置 referrer 政策,浏览器将使用其默认政策。

浏览器 默认 Referrer-Policy / 行为
Chrome 默认值为 strict-origin-when-cross-origin
Firefox 默认值为 strict-origin-when-cross-origin
版本 93 开始,对于严格跟踪保护和隐私浏览用户,限制较少的 referrer 政策 no-referrer-when-downgradeorigin-when-cross-originunsafe-url 将被忽略用于跨站点请求,这意味着对于跨站点请求,referrer 始终会被修剪,无论网站的政策如何。
Edge 默认值为 strict-origin-when-cross-origin
Safari 默认值类似于 strict-origin-when-cross-origin,但有一些特定差异。有关详细信息,请参阅 防止跟踪预防跟踪

设置 referrer 政策的最佳实践

有多种方法可以为您的站点设置 referrer 政策

您可以为不同的页面、请求或元素设置不同的政策。

HTTP 标头和 meta 元素都是页面级别的。用于确定元素的有效政策的优先级顺序如下:

  1. 元素级政策
  2. 页面级政策
  3. 浏览器默认值

示例

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 政策。

如何查看 referrer 政策?

securityheaders.com 可方便地确定特定站点或页面正在使用的政策。

您还可以使用 Chrome、Edge 或 Firefox 中的开发者工具来查看特定请求使用的 referrer 政策。在撰写本文时,Safari 不显示 Referrer-Policy 标头,但会显示已发送的 Referer

A screenshot of the Network panel of Chrome DevTools, showing Referer and Referrer-Policy.
Chrome DevTools 的网络面板,其中选择了请求。

您应该为您的网站设置哪种政策?

我们强烈建议显式设置增强隐私的政策,例如 strict-origin-when-cross-origin(或更严格的政策)。

为什么是“显式”?

如果您未设置 referrer 政策,则将使用浏览器的默认政策—实际上,网站通常会遵循浏览器的默认设置。但这并不理想,因为

  • 不同的浏览器具有不同的默认政策,因此,如果您依赖浏览器默认值,您的站点在不同浏览器中的行为将不可预测。
  • 浏览器正在采用更严格的默认值,例如 strict-origin-when-cross-origin 以及诸如 referrer 修剪之类的机制用于跨源请求。在浏览器默认值更改之前,显式选择增强隐私的政策使您可以进行控制,并帮助您根据需要运行测试。

为什么是 strict-origin-when-cross-origin(或更严格的政策)?

您需要一个安全、增强隐私且有用的政策。“有用”的含义取决于您对 referrer 的期望

  • 安全:如果您的网站使用 HTTPS(如果不是,请将其作为优先事项),您不希望您网站的 URL 在非 HTTPS 请求中泄漏。由于网络上的任何人都可以看到这些 URL,因此泄漏会将您的用户暴露于中间人攻击。no-referrer-when-downgradestrict-origin-when-cross-originno-referrerstrict-origin 政策解决了这个问题。
  • 增强隐私:对于跨源请求,no-referrer-when-downgrade 会共享完整 URL,这可能会导致隐私问题。strict-origin-when-cross-originstrict-origin 仅共享源,而 no-referrer 则不共享任何内容。这为您留下了 strict-origin-when-cross-originstrict-originno-referrer 作为增强隐私的选项。
  • 有用no-referrerstrict-origin 永远不会共享完整 URL,即使对于同源请求也是如此。如果您需要完整 URL,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.referrerReferer 标头。请参阅 详细信息

示例:请求级政策

script.js:

fetch(url, {referrerPolicy: 'no-referrer-when-downgrade'});

您还应该考虑什么?

您的政策应取决于您的网站和用例,由您、您的团队和您的公司确定。如果某些 URL 包含可识别身份或敏感数据,请设置保护性政策。

传入请求的最佳实践

以下是在您的站点使用传入请求的 referrer URL 时应执行操作的一些准则。

保护用户数据

Referer 可能包含私有、个人或可识别身份的数据,因此请确保将其视为此类数据。

传入的 referrer 可能会更改 {referer-can-change}

使用来自传入跨源请求的 referrer 有一些限制

  • 如果您无法控制请求发出者的实现,则无法对您收到的 Referer 标头(和 document.referrer)做出假设。请求发出者可能随时决定切换到 no-referrer 政策,或者更普遍地切换到比以前使用的政策更严格的政策。这意味着您从 Referer 收到的数据比以前更少。
  • 浏览器越来越多地默认使用 Referrer-Policy strict-origin-when-cross-origin。这意味着,如果发送站点未设置任何政策,您现在可能只会在传入的跨源请求中收到源,而不是完整的 referrer URL。
  • 浏览器可能会更改其管理 Referer 的方式。例如,一些浏览器开发人员可能会决定始终将 referrer 修剪为跨源子资源请求中的源,以保护用户隐私。
  • Referer 标头(和 document.referrer)可能包含比您需要的更多的数据。例如,当您只想知道请求是否为跨源时,它可能具有完整 URL。

Referer 的替代方案

如果出现以下情况,您可能需要考虑替代方案

  • 您网站的基本功能使用传入跨源请求的 referrer URL。
  • 您的站点不再收到跨源请求中所需部分的 referrer URL。当请求发出者更改其政策或他们未设置政策并且浏览器默认政策已更改时,就会发生这种情况(如 Chrome 85 中)。

要定义替代方案,首先分析您正在使用的 referrer 的哪一部分。

如果您只需要源

  • 如果您在可以对页面进行顶级访问的脚本中使用 referrer,则 window.location.origin 是一种替代方案。
  • 如果可用,OriginSec-Fetch-Site 等标头会为您提供 Origin 或描述请求是否为跨源,这可能正是您需要的。

如果您需要 URL 的其他元素(路径、查询参数…)

  • 请求参数可能解决您的用例,这可以节省您解析 referrer 的工作。
  • 如果您在可以对页面进行顶级访问的脚本中使用 referrer,则 window.location.pathname 可能作为替代方案。仅提取 URL 的路径部分并将其作为参数传递,这样 URL 参数中任何潜在的敏感信息都不会传递。

如果您不能使用这些替代方案

  • 检查您是否可以更改您的系统以期望请求发出者(例如,site-one.example)显式设置您在某种配置中需要的信息。
    • 优点:对于 site-one.example 用户而言,更明确、更注重隐私、更面向未来。
    • 缺点:可能需要您或您的系统用户付出更多的工作。
  • 检查发出请求的站点是否可能同意为每个元素或每个请求设置 no-referrer-when-downgrade 的 Referrer-Policy。
    • 缺点:对于 site-one.example 用户而言,可能不太注重隐私,可能并非所有浏览器都支持。

跨站请求伪造 (CSRF) 保护

请求发出者始终可以通过设置 no-referrer 政策来决定不发送 referrer,而恶意行为者甚至可以欺骗 referrer。

CSRF 令牌用作您的主要保护。为了获得额外的保护,请使用 SameSite,并使用 Origin(在 POST 和 CORS 请求中可用)和 Sec-Fetch-Site 等标头(如果可用),而不是 Referer

日志和调试

确保保护用户可能在 Referer 中的个人或敏感数据。

如果您仅使用源,请检查是否可以使用 Origin 标头作为替代方案。这可能会以更简单的方式为您提供调试目的所需的信息,而无需解析 referrer。

付款

支付提供商可能会依赖传入请求的 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 源检查成功,您可以继续进行另一种更可靠的验证方法。

为了更可靠地验证付款,请让请求者哈希请求参数以及唯一密钥。然后,支付提供商可以在您这边计算相同的哈希值,并且仅在哈希值与您的计算结果匹配时才接受请求。

当没有 referrer 政策的 HTTP 商家站点重定向到 HTTPS 支付提供商时,Referer 会发生什么情况?

在对 HTTPS 支付提供商的请求中看不到 Referer,因为当网站未设置政策时,大多数浏览器默认使用 strict-origin-when-cross-originno-referrer-when-downgradeChrome 更改为新的默认政策不会改变此行为。

结论

保护性 referrer 政策是为您的用户提供更多隐私的好方法。

要了解有关保护用户隐私的不同技术的更多信息,请参阅我们的安全可靠集合

资源

非常感谢所有审阅者的贡献和反馈 - 特别是 Kaustubha Govind、David Van Cleve、Mike West、Sam Dutton、Rowan Merewood、Jxck 和 Kayce Basques。