文档目录
安全响应头配置

简介

本指南面向DouPHP的安全响应头配置,聚焦以下目标:

  • 解释 headers 配置项中 frame_options、content_type_options、referrer_policy、permissions_policy 的安全意义。
  • 说明 HSTS(HTTP严格传输安全)的配置方法与生效条件。
  • 说明三端(前台、后台、API)中间件如何统一下发安全头。
  • 提供不同安全级别的配置建议与生产环境推荐。
  • 给出安全头的验证方法与常见问题排查。

项目结构

DouPHP 将“安全响应头”作为横切关注点,通过统一的基类中间件在 HTTP 边界下发,三端各自提供薄壳子类以复用相同逻辑;所有策略由集中配置文件驱动。

graph TB
subgraph "配置"
C["config/security.php<br/>security.headers"]
end
subgraph "中间件基类"
M["AbstractSecurityHeadersMiddleware<br/>handle()/sendHeaders()"]
end
subgraph "三端薄壳"
F["front/middleware/SecurityHeadersMiddleware.php"]
A["admin/middleware/SecurityHeadersMiddleware.php"]
P["api/middleware/SecurityHeadersMiddleware.php"]
end
subgraph "路由与注册"
R["MiddlewareRegistry.php"]
E["RouteEntry.php"]
end
C --> M
M --> F
M --> A
M --> P
R --> F
R --> A
R --> P
E --> R

核心组件

  • 配置中心:config/security.php 中的 security.headers 集中管理所有安全头策略,包括 X-Frame-Options、X-Content-Type-Options、Referrer-Policy、Permissions-Policy 以及 HSTS。
  • 中间件基类:AbstractSecurityHeadersMiddleware 负责读取配置并在请求进入管道时尽早下发安全头;HSTS 仅在 HTTPS 且 enabled 为真时下发。
  • 三端薄壳:front/admin/api 下的 SecurityHeadersMiddleware 仅继承基类,保证三端行为一致。
  • 中间件注册:MiddlewareRegistry 负责把各端默认中间件栈与路由级细化组合成最终执行链;RouteEntry 用于识别条目所属端,辅助隔离。

架构总览

安全响应头的下发流程如下:

  • 请求进入对应端的中间件管道。
  • 基类中间件读取 security.headers,按配置逐项设置响应头。
  • 若启用 HSTS,则仅在 HTTPS 且 enabled=true 时附加 Strict-Transport-Security。
  • 继续执行业务控制器并返回响应。
sequenceDiagram
participant Client as "客户端"
participant MW as "SecurityHeadersMiddleware(基类)"
participant Next as "后续中间件/控制器"
participant Resp as "HTTP响应"
Client->>MW : 发起请求
MW->>MW : 读取 config/security.php 的 security.headers
alt content_type_options
MW-->>Resp : 设置 X-Content-Type-Options : nosniff
end
alt frame_options
MW-->>Resp : 设置 X-Frame-Options
end
alt referrer_policy
MW-->>Resp : 设置 Referrer-Policy
end
alt permissions_policy
MW-->>Resp : 设置 Permissions-Policy
end
opt HSTS(HTTPS且enabled)
MW-->>Resp : 设置 Strict-Transport-Security
end
MW->>Next : 调用下一个处理器
Next-->>Client : 业务响应

详细组件分析

配置项与安全意义(headers)

  • frame_options(X-Frame-Options)
    • 作用:控制页面是否允许被 iframe 嵌入,防范点击劫持。
    • 常见值:SAMEORIGIN(仅同源可嵌入)、DENY(禁止任何嵌入)。
    • 配置位置:security.headers.frame_options。
  • content_type_options(X-Content-Type-Options)
    • 作用:强制浏览器遵循 Content-Type,禁用 MIME 嗅探,降低恶意内容执行风险。
    • 开关:true 时下发 nosniff。
    • 配置位置:security.headers.content_type_options。
  • referrer_policy(Referrer-Policy)
    • 作用:控制 Referer 头泄露范围,减少敏感信息外泄。
    • 常见值:strict-origin-when-cross-origin、no-referrer、same-origin 等。
    • 配置位置:security.headers.referrer_policy。
  • permissions_policy(Permissions-Policy)
    • 作用:声明页面可用的浏览器能力(如摄像头、麦克风、地理位置等),最小权限原则。
    • 配置位置:security.headers.permissions_policy。
  • hsts(Strict-Transport-Security)
    • 作用:强制浏览器后续访问使用 HTTPS,防止降级攻击。
    • 字段:
      • enabled:布尔开关,false 时不发送 HSTS。
      • max_age:最大有效期(秒)。
      • subdomains:是否包含子域。
    • 生效条件:必须为 HTTPS 且 enabled=true。
    • 配置位置:security.headers.hsts.*。

HSTS 配置与生效流程

  • 当 security.headers.hsts.enabled=false 时,不会下发 HSTS。
  • 当 enabled=true 且当前请求为 HTTPS 时,根据 max_age 与 subdomains 生成 Strict-Transport-Security。
  • 非 HTTPS 请求即使开启也不会下发,避免首次访问无法建立安全连接的问题。
flowchart TD
Start(["进入中间件"]) --> ReadCfg["读取 security.headers.hsts"]
ReadCfg --> Enabled{"enabled 为真?"}
Enabled -- 否 --> EndNo["不发送 HSTS"]
Enabled -- 是 --> Secure{"isSecure() 为真?"}
Secure -- 否 --> EndNo
Secure -- 是 --> Build["构建 max-age=...; includeSubDomains?"]
Build --> Send["发送 Strict-Transport-Security"]
Send --> EndYes["结束"]

三端统一安全头管理机制

  • 三端均提供独立的 SecurityHeadersMiddleware 薄壳类,继承自同一基类,确保行为一致。
  • 中间件在管道最前置运行,对已匹配路由生效;未命中路由(如 404)不在覆盖范围内。
  • 中间件注册与组装由 MiddlewareRegistry 完成,支持全局默认栈与路由级细化。
classDiagram
class AbstractSecurityHeadersMiddleware {
+handle(next)
-sendHeaders(headers)
}
class FrontSecurityHeadersMiddleware
class AdminSecurityHeadersMiddleware
class ApiSecurityHeadersMiddleware
AbstractSecurityHeadersMiddleware <|-- FrontSecurityHeadersMiddleware
AbstractSecurityHeadersMiddleware <|-- AdminSecurityHeadersMiddleware
AbstractSecurityHeadersMiddleware <|-- ApiSecurityHeadersMiddleware

依赖关系分析

  • 配置依赖:AbstractSecurityHeadersMiddleware 通过 Config::get('security.headers') 获取策略。
  • 运行时依赖:HSTS 判断依赖 Request::isSecure()(由基类注释指明)。
  • 路由与中间件:MiddlewareRegistry 将别名映射到具体中间件类,并按 RouteEntry 的端归属进行装配。
graph LR
CFG["config/security.php"] --> MID["AbstractSecurityHeadersMiddleware"]
MID --> REQ["Request::isSecure()"]
REG["MiddlewareRegistry"] --> MID
ENT["RouteEntry"] --> REG

性能考虑

  • 安全头在管道最前置下发,开销极低,几乎不影响业务处理时间。
  • HSTS 仅在 HTTPS 且 enabled=true 时计算并写入,避免不必要的字符串拼接。
  • 中间件仅对已匹配路由生效,未命中路由(如 404)不触发,减少不必要开销。

故障排查指南

  • 未看到安全头
    • 检查 security.headers 是否配置正确且为数组。
    • 确认请求走的是已匹配路由(中间件仅对命中路由生效)。
    • 确认 headers_sent() 未被提前输出(例如模板或日志过早输出导致无法再写头)。
  • HSTS 未生效
    • 确认当前请求为 HTTPS。
    • 确认 security.headers.hsts.enabled=true。
    • 检查 max_age 与 subdomains 是否符合预期。
  • 第三方代理/反向代理影响
    • 如果站点位于负载均衡或 Nginx 反代后,需正确配置 trusted_proxies,以确保 isSecure() 判定准确。
  • 前端功能异常
    • 若页面出现 iframe 嵌入失败,检查 X-Frame-Options 是否为 DENY。
    • 若跨站 Referer 丢失,检查 Referrer-Policy 是否过于严格。
    • 若某些浏览器 API 不可用,检查 Permissions-Policy 是否限制了相关能力。

结论

DouPHP 通过集中配置与统一中间件实现了三端一致的安全响应头下发机制。建议在生产环境启用严格的基线安全头,并根据需要谨慎启用 HSTS。结合可信代理与 Host 白名单,可进一步提升整体安全性。

附录:不同安全级别配置示例与验证方法

低安全级别(开发/测试)

  • 目标:便于调试与兼容旧功能。
  • 建议:
    • frame_options:空串或 DENY 视业务而定。
    • content_type_options:true。
    • referrer_policy:no-referrer 或宽松策略。
    • permissions_policy:尽量放开必要能力。
    • hsts:enabled=false。
  • 参考路径:config/security.php:62-72

中等安全级别(预生产)

  • 目标:平衡安全与兼容性。
  • 建议:
    • frame_options:SAMEORIGIN。
    • content_type_options:true。
    • referrer_policy:strict-origin-when-cross-origin。
    • permissions_policy:限制非必要能力(如 camera、microphone)。
    • hsts:enabled=false(先观察兼容性)。
  • 参考路径:config/security.php:62-72

高安全级别(生产推荐)

  • 目标:最大化安全防护。
  • 建议:
    • frame_options:SAMEORIGIN(或 DENY,视嵌入需求)。
    • content_type_options:true。
    • referrer_policy:strict-origin-when-cross-origin。
    • permissions_policy:最小化能力集合(如 geolocation=(), microphone=(), camera=())。
    • hsts:enabled=true,max_age 设置为较大值(如一年),subdomains 按需开启。
  • 参考路径:config/security.php:62-72

验证方法

  • 使用浏览器开发者工具查看响应头:
    • X-Content-Type-Options: nosniff
    • X-Frame-Options: SAMEORIGIN/DENY
    • Referrer-Policy: strict-origin-when-cross-origin(或其他设定值)
    • Permissions-Policy: 自定义策略
    • Strict-Transport-Security: max-age=...; includeSubDomains(仅 HTTPS 且 enabled=true)
  • 使用命令行工具(如 curl)检查:
  • 在线扫描工具:
    • 使用安全扫描器检测响应头是否齐全与正确。
添加日期:2026-10-05