首页/开发/正则与编码速查/HTML 实体转义与注入防护

HTML 实体转义与注入防护

转义要按输出上下文选择规则:HTML 文本内容转 & 与尖括号,属性值还要处理引号,URL 与脚本、样式上下文各有编码方式;只用一套规则处理所有位置,正是注入类漏洞的常见来源。

正则与编码速查开发更新于 2026-10-17
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌‌‌​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​​​‌​‌‌​‌​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌‌​‌​​​‌‌​‌​​‌​‌‌‌​‌​​​‌‌‌‌​​‌​​‌​‌‌​‌​‌‌​​‌​‌​‌‌‌​​‌‌​‌‌​​​‌‌​‌‌​​​​‌​‌‌‌​​​​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​​‌​‌‌​‌​‌‌‌‌​​​​‌‌‌​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​

为什么必须分上下文

同一段用户数据可能落进不同位置:标签之间的文本、属性值、链接地址、脚本片段、样式规则。每个位置的解析规则不同,需要转义的字符也不同:文本内容只需处理 & 与尖括号;属性值还需要处理引号(未加引号的属性限制更严);URL 位置要防协议与百分号问题;脚本上下文则要用相应语言的转义规则。用一套规则包打天下,就会出现「已经转义了却仍能注入」的情况。

基本信息

HTML 文本内容转义 & 与尖括号
属性值(带引号)额外转义引号,属性值必须用引号包裹
URL 位置百分号编码,并校验协议白名单
脚本上下文使用对应语言的转义,优先改为传递数据而非拼接代码
样式上下文避免拼接用户数据,必要时做严格数值校验
通用原则在输出边界做一次、按上下文选择规则的转义

典型使用场景

  • 评论与昵称展示:文本位置按文本规则转义
  • 链接与图片地址:校验协议、必要时编码,禁止直接拼接脚本协议
  • 模板渲染:了解模板引擎是否自动转义,避免手动重复转义或漏转
  • 富文本编辑:先白名单过滤标签与属性,再按位置输出
  • 前端动态插入:使用设置文本内容的接口而不是直接写入标记

正确与错误示例

正确与错误示例
# 错误:只做宽松过滤,标签仍可注入
# <div>欢迎 {{ name }}</div>   而 name 未转义 → 可插入 <script> 或属性事件
# 正确:文本位置转义 & 与尖括号
# <div>欢迎 &lt;b&gt;张三&lt;/b&gt;</div>
# 正确:属性值使用引号包裹并转义引号
# <a title="&quot; onmouseover=&quot;x&quot;">链接</a>   # 用户内容里的引号被转义
# 正确:URL 位置校验协议白名单,拒绝脚本协议
python -c "import html; print(html.escape('" onmouseover="alert(1)'))"   # 转义属性注入
python -c "import urllib.parse as u; print(u.quote('a b&c'))"             # URL 位置使用百分号编码

上下文与转义要求

输出位置需处理常见错误
标签之间的文本& 与尖括号漏转 & 导致实体与内容混淆
属性值(键值对)引号与尖括号属性未加引号,空格即可逃逸
URL 参数与路径百分号编码与协议白名单未校验协议,允许脚本协议执行
脚本片段按语言转义或改传数据直接拼接字符串造成代码注入
样式值严格数值或枚举校验拼接用户数据造成样式注入
黑名单过滤不可靠:只删除某个标签名或事件名,攻击者可用其他等价写法绕过。正确顺序是「按上下文转义输出」加上「必要的白名单过滤」,而不是在输入端做字符替换。
模板引擎与前端框架通常默认转义,「关闭自动转义」这一操作要审慎对待:每次显式关闭都必须确认数据来源可信,或已经过白名单净化,否则就等于把注入风险交还给调用方。
转义与净化是两件事:转义让内容「原样显示」,净化决定「允许显示哪些格式」。富文本场景两者都要有——先用白名单净化允许的标签与属性,再在输出位置按上下文转义剩余内容。

易错点

  • 只用一套转义规则覆盖所有位置:属性与 URL 位置仍可注入 → 按输出上下文选择对应规则
  • 属性值不加引号:用户内容中的空格就能逃逸出属性,插入事件处理器 → 属性值统一用引号包裹并转义引号
  • 在 URL 位置拼接用户输入且不校验协议:脚本协议被触发 → 使用协议白名单并做百分号编码
  • 先转义再拼接或多次转义:显示结果出现实体字符,用户看到 &lt; 而不是符号 → 在输出边界一次性处理
  • 依赖黑名单过滤:等价写法可绕过限制 → 采用白名单净化加重上下文转义

数据来源与参考

  • OWASP:Cross Site Scripting Prevention Cheat Sheet
  • OWASP:Output Encoding 与上下文转义规则
  • WHATWG HTML 标准:字符引用与属性语法

整理校对:其其网ICT文档中心 · 本页地址:docs.qiqicto.com/regex/html-entity-escaping-xss.html

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌‌‌​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​​​‌​‌‌​‌​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌‌​‌​​​‌‌​‌​​‌​‌‌‌​‌​​​‌‌‌‌​​‌​​‌​‌‌​‌​‌‌​​‌​‌​‌‌‌​​‌‌​‌‌​​​‌‌​‌‌​​​​‌​‌‌‌​​​​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​​‌​‌‌​‌​‌‌‌‌​​​​‌‌‌​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​