文档目录
XSS防护措施

简介

本指南面向DouPHP项目的XSS(跨站脚本)防护,围绕“输入过滤、输出编码、内容安全策略CSP”三大维度,结合框架内置的XSS工具类与安全响应头中间件,提供可落地的配置与最佳实践。文档重点包括:

  • 使用内置XSS工具进行安全的HTML白名单过滤与属性校验
  • 在模板渲染时进行上下文感知的输出编码
  • 通过安全响应头中间件下发基线安全头(不含CSP),并给出CSP落地建议
  • 针对JavaScript事件处理器、URL协议、样式等高风险场景的处理方案
  • 常见攻击场景与防御策略对照表

项目结构

与XSS防护直接相关的代码主要分布在以下位置:

  • 核心XSS过滤能力:core/infra/Security/Xss.php
  • 门面与辅助函数:core/facade/Xss.php、core/foundation/container/helpers.php
  • 安全响应头中间件:core/foundation/middleware/AbstractSecurityHeadersMiddleware.php 及各端薄壳实现(如 front/middleware/SecurityHeadersMiddleware.php)
  • 安全配置:config/security.php
graph TB
A["控制器/服务"] --> B["xss() 或 Xss 门面"]
B --> C["Xss::filterHtml / comment / content / rss"]
A --> D["视图渲染"]
D --> E["模板变量输出编码"]
A --> F["安全响应头中间件"]
F --> G["安全头: X-Frame-Options / Referrer-Policy / Permissions-Policy / HSTS(可选)"]

核心组件

  • Xss 工具类(核心过滤引擎)
    • 提供 filterHtml、comment、content、rss 等方法,支持安全模式、标签白名单、属性白名单、URL协议白名单、样式过滤、嵌套合法性检查、标签平衡等。
    • 关键配置项:safe、elements、deny_elements、deny_attribute、safe_allow、parent、remove_comments、remove_cdata、clean_control_chars、balance_tags、keep_bad。
  • Xss 门面与 xss() 辅助函数
    • 通过容器解析 Xss 实例,便于在控制器/服务中统一调用。
  • 安全响应头中间件
    • 从 config/security.php 读取 headers 配置,在管道前置下发基线安全头(不含 CSP)。HSTS 仅在 HTTPS 且开启时下发。

架构总览

下图展示请求进入后,XSS防护在“输入过滤—渲染—响应头”三阶段的协作方式。

sequenceDiagram
participant U as "用户"
participant C as "控制器/服务"
participant X as "Xss 工具"
participant V as "模板渲染器"
participant M as "安全响应头中间件"
participant R as "浏览器"
U->>C : 提交表单/参数
C->>X : 调用 xss()->filterHtml/comment/content/rss
X-->>C : 返回已过滤的HTML/文本
C->>V : 将安全数据传入模板
V-->>R : 输出HTML配合上下文编码
C->>M : 生成响应
M-->>R : 下发安全响应头X-Frame-Options/Referrer-Policy/Permissions-Policy/HSTS

详细组件分析

Xss 工具类:输入过滤与白名单

  • 处理流程概览
    • 清理BOM/空字节/控制字符
    • 移除DOCTYPE、注释、CDATA
    • 实体规范化
    • 标签扫描与白名单校验(含 safe/safe_allow/elements/deny_elements)
    • 属性白名单校验(全局+标签专属+aria-/data-前缀)
    • URL协议白名单校验(含 data:image/* 特例)
    • style 属性深度过滤(url()、危险关键字、转义绕过)
    • srcset 多值URL过滤
    • 标签嵌套合法性检查与闭合平衡
  • 关键方法
    • filterHtml(html, config):通用HTML过滤入口
    • comment(html):评论场景的严格白名单
    • content(html):内容场景允许更多标签
    • rss(html):RSS场景的有限标签集
  • 白名单与限制要点
    • 默认安全模式下禁止大量危险标签(script、iframe、object、svg、math等)
    • 仅允许特定URL协议(http/https/mailto/tel/ftp/ftps 等),对 javascript/vbscript 等危险协议严格拒绝
    • 对 on* 事件处理器一律丢弃
    • style 中 url() 仅允许 http/https,data:image/* 白名单放行
    • 支持 safe_allow 与 elements 精细控制
flowchart TD
Start(["开始"]) --> Clean["清理BOM/空字节/控制字符"]
Clean --> Strip["移除DOCTYPE/注释/CData"]
Strip --> Normalize["实体规范化"]
Normalize --> Scan["扫描标签并校验白名单"]
Scan --> Attrs{"属性合法?"}
Attrs -- 否 --> Drop["丢弃非法属性/标签"]
Attrs -- 是 --> UrlCheck{"是否URL属性?"}
UrlCheck -- 是 --> UrlFilter["协议白名单/危险协议检测"]
UrlCheck -- 否 --> StyleCheck{"是否style?"}
StyleCheck -- 是 --> StyleFilter["过滤url()/危险关键字/转义"]
StyleCheck -- 否 --> Nesting{"嵌套合法?"}
Nesting -- 否 --> Drop
Nesting -- 是 --> Balance["标签平衡"]
Balance --> End(["结束"])

门面与辅助函数:便捷调用

  • xss() 辅助函数:从容器解析 Xss 单例,供业务层统一调用
  • Xss 门面:静态门面,底层委托到 Xss 类,提供 setConfig/getConfig/resetConfig/filterHtml/comment/content/rss/text/post 等静态方法

安全响应头中间件:基线安全头

  • 行为说明
    • 从 config/security.php 的 security.headers 读取配置
    • 下发 X-Content-Type-Options、X-Frame-Options、Referrer-Policy、Permissions-Policy
    • HSTS 仅在 HTTPS 且 enabled=true 时下发
    • 仅覆盖命中路由的请求(404自渲染不在范围内)
  • 配置项
    • frame_options、content_type_options、referrer_policy、permissions_policy、hsts.enabled/max_age/subdomains
classDiagram
class AbstractSecurityHeadersMiddleware {
+handle(next) mixed
-sendHeaders(headers) void
}
class SecurityHeadersMiddleware_Front {
}
AbstractSecurityHeadersMiddleware <|-- SecurityHeadersMiddleware_Front

模板输出编码:上下文感知

  • 原则
    • 所有用户可控数据在模板输出时必须进行上下文相关编码:HTML正文、HTML属性、JavaScript、CSS、URL
  • 建议
    • 优先使用模板引擎提供的自动转义功能;若需输出富文本,先经 Xss 过滤再放入模板
    • 避免在模板中拼接JS/CSS字符串;如需动态注入,使用结构化数据并通过安全API渲染

依赖关系分析

  • 调用链
    • 业务层通过 xss() 或 Xss 门面调用 core/infra/Security/Xss.php 中的过滤逻辑
    • 安全响应头由 AbstractSecurityHeadersMiddleware 在各端薄壳中统一下发
  • 外部依赖
    • 配置来自 config/security.php
    • 中间件依赖 Request 的安全判断(如 isSecure)
graph LR
H["helpers.php<br/>xss()"] --> F["facade/Xss.php"]
F --> I["infra/Security/Xss.php"]
C["config/security.php"] --> M["AbstractSecurityHeadersMiddleware"]
M --> S["各端 SecurityHeadersMiddleware"]

性能考量

  • 过滤成本
    • 正则扫描与多次解码(URL/实体)会带来CPU开销,建议在批量处理时复用配置或缓存结果
  • 白名单粒度
    • 过宽的 elements=* 会提升复杂度;尽量限定允许的标签集合
  • 中间件
    • 安全响应头中间件在管道前置执行,开销极低

故障排查指南

  • 富文本被过度过滤
    • 检查 Xss 配置:safe、elements、deny_elements、safe_allow
    • 确认是否需要启用非安全模式下的额外标签(谨慎)
  • 链接无法跳转或报错
    • 检查 href/src/action 等URL属性是否使用了被拒绝的协议(如 javascript)
    • 确认是否在 style 中使用了不被允许的 url()
  • 页面布局错乱
    • 检查 balance_tags 与标签嵌套规则导致的闭合调整
  • 安全头未生效
    • 确认中间件已注册且命中路由
    • 检查 config/security.php 的 headers 配置是否正确

结论

DouPHP提供了完善的XSS防护基础设施:以 Xss 工具为核心的输入过滤、以安全响应头中间件为基础的基线安全头下发,以及模板层的上下文编码要求。遵循“最小权限白名单、严格协议校验、禁用事件处理器、安全头兜底”的原则,可有效抵御常见XSS攻击。对于需要富文本的场景,应结合业务需求精细化配置,并在前后端协同下确保输出安全。

附录

常用配置与用法速查

  • 获取XSS工具
    • 使用 xss() 辅助函数或 Xss 门面
  • 过滤富文本
    • 使用 content(html) 或自定义 filterHtml(html, config)
  • 评论/短文本
    • 使用 comment(html)
  • RSS内容
    • 使用 rss(html)
  • 安全响应头
    • 在 config/security.php 中配置 security.headers

常见XSS攻击场景与防护方案

  • 反射型XSS(URL参数回显)
    • 输入:xss()->filterHtml() 或 xss()->text()
    • 输出:模板中按上下文编码
  • 存储型XSS(评论/留言)
    • 输入:xss()->comment() 或 content()
    • 输出:模板中按上下文编码
  • 基于DOM的XSS(前端拼接)
    • 后端输出必须编码;前端避免 innerHTML 拼接用户数据
  • 事件处理器注入(on*)
    • 过滤器会丢弃 on* 属性;模板中不要拼接事件处理器
  • 危险协议(javascript:)
    • URL属性会被拒绝;style 中 url() 仅允许 http/https 与 data:image/*
  • CSS注入
    • style 属性经过深度过滤,移除危险关键字与转义绕过
添加日期:2026-10-05