Referer 问题
Referer(拼写错误)头部包含请求的地址(例如,用户从哪个网页链接到当前请求的网页,或者加载图片的页面地址)。这有许多无害的用途,包括分析、日志记录或优化缓存。然而,也存在一些更有问题的用途,例如跟踪或窃取信息,甚至仅仅是无意中泄露敏感信息的副作用。
例如,考虑一个页脚带有社交媒体链接的“重置密码”页面。如果用户点击了该链接,根据信息共享的方式,社交媒体网站可能会收到重置密码的 URL,并且仍然可以利用共享的信息,从而可能危及用户安全。
同理,嵌入在你页面中的第三方网站的图片可能导致敏感信息泄露给第三方。即使安全没有受到威胁,这些信息也可能不是用户希望共享的内容。
我们如何解决这个问题?
通过合理的应用程序设计可以缓解大部分风险。一个合理的应用程序可以通过生成一次性使用的密码重置 URL,或将其与唯一的用户令牌结合来消除此类风险。通过更安全的方式传输敏感数据也可以降低风险。
应尽可能使用 POST 而不是 GET,以避免通过 URL 将敏感数据传递给其他位置。
你应该始终为你的网站使用 HTTPS。这有很多安全优势,包括 HTTPS 网站永远不会向非 HTTPS 网站传输 Referer 信息。现在由于绝大多数网站都使用 HTTPS,这个建议的相关性有所降低,但仍然值得考虑。
此外,你应该考虑从你网站的安全区域(如重置密码页面、支付表单、登录区域等)中移除任何第三方内容(例如,嵌入在 <iframe> 中的社交网络小部件)。
你还可以通过以下方式缓解此类风险:
- 服务器上的 Referrer-Policy头部,用于控制通过Referer头部发送哪些信息。例如,`no-referrer` 指令将完全省略 Referer 头部。
- HTML 元素上易于泄露此类信息的 `referrerpolicy` 属性(例如 <img>和<a>)。例如,可以将其设置为 `no-referrer` 以完全停止发送 `Referer` 头部。
- HTML 元素上设置为 noreferrer的 `rel` 属性,这些元素易于泄露此类信息(例如<form>和<a>)。
- 使用 `referrer` 作为 <meta>元素的 name,并将 content 设置为 `no-referrer`,以禁用整个文档的 Referer 头部。请参阅 Referrer-Policy 与 HTML 的集成。
- “退出页面”技术。
注重安全的服务器端框架通常内置了此类问题的缓解措施,例如:
- Django 安全性(特别是 跨站请求伪造 (CSRF) 防护)。
- Helmet referrer-policy — 用于在 Node.js/Express 应用中设置 Referrer-Policy 的中间件(另请参阅 Helmet 以获取更多安全措施)。
策略和要求
为你的项目团队编写一套安全和隐私要求,明确使用此类功能来缓解相关风险,这是有意义的。你应该寻求网络安全专家的帮助来撰写这些要求,并同时考虑用户需求和福祉,以及其他问题,如由《欧盟通用数据保护条例》(GDPR) 等立法强制执行的政策和法规。