
Bleach 默认会严格过滤 style 属性中的 CSS 声明,但通过显式传入 CSSSanitizer 实例并配置其白名单,可安全地保留所需(甚至全部)CSS 属性,本文详解实现方法与注意事项。
bleach 默认会严格过滤 `style` 属性中的 css 声明,但通过显式传入 `csssanitizer` 实例并配置其白名单,可安全地保留所需(甚至全部)css 属性,本文详解实现方法与注意事项。
在使用 Python 的 Bleach 库进行 HTML 清洗时,style 属性常被默认移除或大幅精简——这是因为 Bleach 内置的 CSS 过滤机制(基于 cssutils)仅允许一组预设的安全 CSS 属性(如 color、font-family、text-align 等),其余如 margin、padding、border、background 等均会被静默丢弃。
要保留更完整的 CSS 样式(例如邮件模板中常见的内联样式),关键在于启用并自定义 CSSSanitizer,而非依赖默认行为。
✅ 正确做法:显式传入 CSSSanitizer
Bleach 的 clean() 函数支持 css_sanitizer 参数,接收一个实现了 sanitize_css() 方法的对象。bleach.css_sanitizer.CSSSanitizer 是官方提供的类,它允许你通过 allowed_css_properties 参数扩展白名单,甚至设为 None 以允许所有标准 CSS 属性(注意:不包括危险属性如 expression、url() 中的 JS 协议等,底层仍受安全策略约束)。
以下是完整、可运行的修复示例:
立即学习“前端免费学习笔记(深入)”;
import bleach
from bleach.css_sanitizer import CSSSanitizer
# 允许的标签与属性(保持原有逻辑)
ALLOWED_TAGS = ['table', 'tr', 'td', 'p', 'h3', 'b', 'br', 'div', 'h5', 'hr', 'i', 'span', 'strong', 'u']
ALLOWED_ATTRIBUTES = {
"table": ["width", "style"],
"tr": ["style"],
"td": ["width", "style"],
"h3": ["style"],
"p": ["style"]
}
def sanitize_html_body(value):
# ✅ 关键:传入自定义 CSSSanitizer,允许全部标准 CSS 属性
css_sanitizer = CSSSanitizer(
allowed_css_properties=None # ← None 表示允许所有标准 CSS 属性(安全范围内)
)
return bleach.clean(
value,
tags=ALLOWED_TAGS,
attributes=ALLOWED_ATTRIBUTES,
strip=True,
css_sanitizer=css_sanitizer # ← 必须显式传入!
)
# 测试 HTML(含丰富内联样式)
html_body = '''<table style="margin:0;padding:0;border:0;font-family:Arial, Helvetica, sans-serif;border-collapse:collapse;width:100%;color:#000000;" width="100%">
<tr style="margin:0;padding:0;font-family:Arial, Helvetica, sans-serif;">
<td style="margin:0;padding:0;vertical-align:top;text-align:center;width:60px;background:#ff5400;" width="60">
<b>Icon</b>
</td>
<td style="padding:18px;background:#f6f6f6;">
<h3 style="font-size:18px;font-weight:bold;margin-bottom:6px;">test567</h3>
<p style="font-size:12px;">Tes1234</p>
</td>
</tr>
</table>'''
print(sanitize_html_body(html_body))? 提示:
allowed_css_properties=None并非“放行一切”,而是启用 Bleach 内置的全量标准 CSS 属性白名单(约 300+ 项),已排除behavior、filter、font-feature-settings(含危险值)等高风险属性,兼顾功能与安全。
⚠️ 注意事项与最佳实践
-
不要省略
css_sanitizer=参数:若未传入,Bleach 将使用None(即禁用 CSS 解析),导致所有style值被清空。 -
避免
allowed_css_properties=[]:空列表会禁止所有 CSS,与目标相悖。 -
谨慎对待
url()和@import:CSSSanitizer默认禁止所有url()函数内的外部资源引用(防 XSS),即使你放开属性,background: url(http://xss.com/)仍会被移除。 -
<style></style>标签需额外处理:本文方案仅作用于style属性;若需清洗<style></style>标签内容,请配合styles=True参数及css_sanitizer。 -
生产环境建议最小化白名单:如仅需邮件兼容样式,可显式指定:
CSSSanitizer(allowed_css_properties=[ 'font-family', 'font-size', 'font-weight', 'color', 'background', 'margin', 'padding', 'border', 'text-align', 'vertical-align', 'width', 'height', 'line-height' ])
通过合理配置 CSSSanitizer,你既能满足复杂排版需求,又无需放弃 Bleach 的安全防护能力——这才是 Web 内容清洗的工程化实践之道。


















