文档目录
Referrer-Policy配置

简介

本文件为 DouPHP 的 Referrer-Policy 安全响应头配置指南。内容涵盖:

  • 各策略值的作用与差异(no-referrer、no-referrer-when-downgrade、origin、origin-when-cross-origin、same-origin、strict-origin、strict-origin-when-cross-origin、unsafe-url)
  • 引用信息泄露的安全风险与隐私保护需求
  • 不同业务场景下的推荐配置(表单提交、第三方集成等)
  • 与 CSP 中 referrer 指令的关系
  • 兼容性与测试方法
  • 在 DouPHP 中的具体落地位置与修改方式

项目结构

DouPHP 通过“中间件 + 配置”的方式统一下发基线安全响应头,其中包含 Referrer-Policy。关键路径如下:

  • 配置入口:config/security.php 中的 security.headers.referrer_policy
  • 中间件基类:core/foundation/middleware/AbstractSecurityHeadersMiddleware.php
  • 三端薄壳中间件:front/admin/api 下的 SecurityHeadersMiddleware.php(继承基类)
  • HTML 标签级 referrerpolicy 支持:core/infra/security/Xss.php(允许 a/img/area/iframe 等标签携带 referrerpolicy 属性)
graph TB
A["请求进入"] --> B["前端/后台/API 路由匹配"]
B --> C["SecurityHeadersMiddleware(前端/后台/API)"]
C --> D["AbstractSecurityHeadersMiddleware.handle()"]
D --> E["读取 config/security.php 的 security.headers"]
E --> F{"referrer_policy 是否设置?"}
F -- 是 --> G["发送 Referrer-Policy 响应头"]
F -- 否 --> H["不发送该头"]
G --> I["继续处理请求"]
H --> I

核心组件

  • 配置项 security.headers.referrer_policy:控制是否下发以及下发的 Referrer-Policy 值。空串表示关闭该响应头。
  • 中间件基类 AbstractSecurityHeadersMiddleware:在管道最前置读取配置并发送一组基线安全响应头(含 Referrer-Policy)。
  • 三端薄壳中间件:分别位于 front/admin/api,行为一致,仅继承基类。
  • XSS 白名单:允许在 a/img/area/iframe 等标签上设置 referrerpolicy 属性,用于页面内细粒度覆盖。

架构总览

Referrer-Policy 在 DouPHP 中的生效流程:

  1. 请求命中路由后,进入对应端的 SecurityHeadersMiddleware。
  2. 调用基类的 handle(),读取 security.headers。
  3. 若 referrer_policy 非空,则发送 Referrer-Policy 响应头。
  4. 后续控制器/视图渲染时,HTML 标签可继续使用 referrerpolicy 进行更细粒度的覆盖(如特定链接或图片)。
sequenceDiagram
participant U as "浏览器"
participant MW as "SecurityHeadersMiddleware(前端/后台/API)"
participant BASE as "AbstractSecurityHeadersMiddleware"
participant CFG as "Config(security.headers)"
participant S as "服务端处理器"
U->>MW : HTTP 请求
MW->>BASE : handle(next)
BASE->>CFG : 读取 security.headers
alt referrer_policy 已设置
BASE-->>U : 响应头 Referrer-Policy : <值>
else 未设置
BASE-->>U : 不发送 Referrer-Policy
end
BASE-->>S : 继续处理请求
S-->>U : 业务响应

详细组件分析

配置层:config/security.php

  • 位置:security.headers.referrer_policy
  • 默认值:strict-origin-when-cross-origin
  • 行为:
    • 设置为空字符串时,中间件不会下发 Referrer-Policy 响应头。
    • 设置为其他合法策略值时,将按该值下发。

中间件层:AbstractSecurityHeadersMiddleware

  • 作用:在管道最前置下发基线安全响应头(包括 Referrer-Policy)。
  • 关键点:
    • 仅在 headers_sent() 之前执行,避免重复或失败。
    • 仅对已匹配路由生效;404 由 Router 自渲染,不在中间件覆盖范围内。
    • 同时下发 X-Content-Type-Options、X-Frame-Options、Permissions-Policy、HSTS(HTTPS+enabled)。

三端薄壳中间件

  • front/middleware/SecurityHeadersMiddleware.php
  • admin/middleware/SecurityHeadersMiddleware.php
  • api/middleware/SecurityHeadersMiddleware.php
  • 说明:三者均继承基类,行为一致,便于按端复用同一套安全头策略。

标签级覆盖:XSS 白名单中的 referrerpolicy

  • 支持在 a、img、area、iframe 等标签上使用 referrerpolicy 属性,实现页面内细粒度控制。
  • 适用场景:
    • 某些外链需要放宽策略以获取必要引用信息。
    • 敏感资源希望进一步收紧到 no-referrer。

依赖关系分析

  • 中间件依赖配置:AbstractSecurityHeadersMiddleware 从 Config 读取 security.headers.referrer_policy。
  • 三端中间件依赖基类:front/admin/api 的 SecurityHeadersMiddleware 均继承基类,共享逻辑。
  • 页面级能力依赖 XSS 白名单:允许在特定标签使用 referrerpolicy 属性。
classDiagram
class AbstractSecurityHeadersMiddleware {
+handle(next)
-sendHeaders(headers)
}
class FrontSecurityHeadersMiddleware
class AdminSecurityHeadersMiddleware
class ApiSecurityHeadersMiddleware
class Config {
+get(key, default)
}
FrontSecurityHeadersMiddleware --> AbstractSecurityHeadersMiddleware : "继承"
AdminSecurityHeadersMiddleware --> AbstractSecurityHeadersMiddleware : "继承"
ApiSecurityHeadersMiddleware --> AbstractSecurityHeadersMiddleware : "继承"
AbstractSecurityHeadersMiddleware --> Config : "读取 security.headers"

性能与兼容性

  • 性能影响:Referrer-Policy 响应头下发开销极低,几乎无性能影响。
  • 兼容性:
    • 现代浏览器普遍支持 Referrer-Policy。
    • 旧版浏览器会忽略未知策略值,因此不建议使用非法值。
    • 若需完全禁用该头,可将 referrer_policy 设为空串。
  • 与 HSTS 的关系:HSTS 仅在 HTTPS 且 enabled 时下发,不影响 Referrer-Policy 的行为。

故障排查

  • 现象:响应头未出现 Referrer-Policy
    • 检查 config/security.php 中 security.headers.referrer_policy 是否为空串。
    • 确认请求命中了路由(404 由 Router 自渲染,不在中间件覆盖范围)。
    • 确认未在更早阶段输出响应头导致 headers_sent() 为真。
  • 现象:部分链接仍泄露完整 URL
    • 检查页面中是否存在 referrerpolicy 属性覆盖了全局策略。
    • 针对特定外链或敏感资源,可在相应标签上设置更严格的 referrerpolicy。
  • 现象:第三方脚本或 SDK 无法获取必要引用
    • 评估是否需要放宽策略(如 origin-when-cross-origin),或在局部使用 referrerpolicy 精细控制。

结论

  • DouPHP 通过集中式配置与中间件下发 Referrer-Policy,默认采用严格平衡的 strict-origin-when-cross-origin。
  • 可通过配置快速调整全站策略,并通过页面标签级 referrerpolicy 进行细粒度覆盖。
  • 建议在大多数场景保持默认或更严格策略;仅在确有需要时放宽,并对敏感资源收紧。

附录:策略值与场景建议

策略值说明

  • no-referrer:完全不发送 Referer 头,适用于高隐私场景,但可能影响统计与外链功能。
  • no-referrer-when-downgrade:仅在 HTTPS→HTTP 降级时不发送 Referer,其余情况正常发送。
  • origin:跨域请求只发送源(scheme+host+port),不发送路径;适合仅需来源的场景。
  • origin-when-cross-origin:同源完整 URL,跨域仅发送源;兼顾统计与隐私,常用默认。
  • same-origin:仅同源发送完整 Referer,跨域不发送;适合强隔离场景。
  • strict-origin:跨域仅发送源,且 HTTPS→HTTP 降级时不发送;比 origin-when-cross-origin 更严格。
  • strict-origin-when-cross-origin:同源完整 URL,跨域仅发送源,且 HTTPS→HTTP 降级时不发送;当前默认。
  • unsafe-url:始终发送完整 URL,即使跨域和降级;存在较高隐私风险,不推荐。

业务场景推荐

  • 表单提交(登录、注册、留言、订单提交等)
    • 推荐:strict-origin-when-cross-origin 或 same-origin
    • 理由:防止敏感路径被第三方站点获取,同时保留必要的来源信息用于站内分析。
  • 第三方集成(广告、统计、支付回调)
    • 推荐:origin-when-cross-origin 或 strict-origin
    • 理由:多数第三方仅需来源即可工作;如需完整 URL,谨慎评估风险后再放宽。
  • 用户分享与外链
    • 推荐:origin-when-cross-origin
    • 理由:平衡隐私与外链统计;必要时对个别外链使用 referrerpolicy 属性精细化控制。
  • 管理后台
    • 推荐:same-origin 或 strict-origin-when-cross-origin
    • 理由:后台通常不应向外部泄露访问路径;必要时可结合 CSP 与权限控制。

与 CSP 中 referrer 指令的关系

  • CSP 的 referrer 指令可限制页面发起的请求是否携带引用信息,与 Referrer-Policy 共同作用。
  • 优先级与协作:
    • Referrer-Policy 是响应头策略,作用于整个文档及其子资源。
    • CSP 的 referrer 指令可对特定上下文做更细粒度的限制。
    • 两者不一致时,浏览器会综合判断,通常以更严格者为准。
  • 建议:
    • 优先通过 Referrer-Policy 设定全局策略。
    • 在需要更强控制的上下文中,配合 CSP 的 referrer 指令进行补充。

兼容性与测试方法

  • 兼容性:
    • 主流现代浏览器均支持 Referrer-Policy。
    • 旧版浏览器会忽略未知策略值,建议使用标准值。
  • 测试方法:
    • 使用浏览器开发者工具查看响应头是否包含 Referrer-Policy 及值是否正确。
    • 在不同场景下(同源、跨域、HTTPS→HTTP 降级)观察 Referer 头的实际行为。
    • 对关键外链与第三方脚本进行回归测试,确保功能不受影响。
    • 在模板中使用 referrerpolicy 属性进行局部覆盖,验证其优先级与效果。
添加日期:2026-10-05