Ruby Sanitize<5.2.1的HTML sanitization绕过
字数 1102 2025-08-22 12:23:47
Ruby Sanitize <5.2.1 HTML Sanitization 绕过漏洞分析
漏洞概述
Ruby Sanitize库在5.2.1版本之前存在一个HTML sanitization绕过漏洞,当使用RELAXED配置时,攻击者可以完全绕过该库的安全过滤机制。此漏洞由Securitum团队在2020年6月16日披露,允许攻击者注入恶意脚本并执行跨站脚本(XSS)攻击。
Sanitize库简介
Sanitize是一个Ruby HTML清理库,其主要功能是:
- 接收不受信任的HTML标记
- 删除潜在的不安全元素和属性
- 生成"安全"的HTML输出
Sanitize基于白名单机制工作,默认提供几种预定义的白名单配置,其中RELAXED配置允许以下元素:
a abbr address article aside bdi bdo blockquote body br caption cite
code col colgroup data dd del dfn div dl dt figcaption figure footer
h1 h2 h3 h4 h5 h6 head header hgroup hr html img ins kbd li main mark
nav ol p pre q rp rt ruby s samp section small span strike style sub
summary sup sup table tbody td tfoot th thehead time title tr ul var wbr
漏洞原理
1. STYLE元素的特殊行为
HTML解析器对<style>元素有以下特殊处理:
- 实体解码行为:在
<style>元素内,HTML实体不会被解码<div>I <3 XSS</div> <!-- 实体被解码 --> <style>I <3 XSS</style> <!-- 实体保持原样 --> - 序列化行为:大多数元素的文本内容会被转义,但
<style>元素的内容会按字面意义呈现
2. 外部内容的特殊处理
当<style>元素位于<svg>或<math>元素内时(称为"外部内容"),上述行为会反转:
- 实体会被解码
- 内容会被HTML编码
3. 漏洞利用点
RELAXED配置允许<style>元素但不允许<svg>和<math>元素。攻击者可以构造以下payload:
<svg><style>/*</style><img src onerror=alert(1)*/
处理流程:
- 解析器将payload解析为DOM树,包含
<svg>和<style>元素 - Sanitize删除不在白名单中的
<svg>元素,但保留了其内容 - 剩余的
<style>元素被序列化时,由于不在<svg>内,实体不会被编码 - 最终输出变为:
<style>/*</style>*/ - 浏览器解析时会执行XSS
漏洞修复
修复方案包括:
- 删除
<svg>和<math>元素时,同时删除其内容 - 更新至Sanitize 5.2.1或更高版本
技术要点总结
- 实体编码/解码差异:
<style>元素内外实体处理方式不同 - 序列化行为差异:
<style>元素内容是否会被编码取决于父元素 - DOM操作漏洞:删除元素时未正确处理其内容
- 白名单绕过:利用允许的元素(
<style>)间接引入被禁止的元素
防御建议
- 及时更新Sanitize库至最新版本
- 审查自定义白名单配置
- 考虑使用更严格的配置而非RELAXED
- 实施多层防御,如CSP(内容安全策略)
此漏洞展示了HTML解析和序列化过程中微妙的行为差异如何导致安全漏洞,强调了深入理解HTML规范在处理用户输入时的重要性。