#224
Blogger 模板静默拒绝(Silent Reject)事故排查全记录
在 Blogger 平台中,当我们上传自定义的主题 XML 文件时,Blogger 后台界面往往会弹出“主题已更新”的成功提示。然而,刷新博客首页却会发现页面布局没有任何变化,依然保留着旧的主题风格。即使清除缓存、开启无痕模式也是如此。我们经过了整整三天的排查,终于揪出了导致这一静默拒绝事故的幕后黑手:仅仅是因为一个写在 CSS 注释中的 HTML 标签。
排查第一阶段:双向代码验证
为了确认问题所在,我们利用 Playwright 在无头浏览器环境下编写了测试脚本。通过 Blogger 的 CodeMirror 在线编辑器直接调用 CodeMirror.getValue() 获取后台实际保存의 模板源码,并将其与我们本地上传的文件进行逐字节对比。对比结果令人震惊:Blogger 后台静默过滤并丢弃了我们 XML 代码中的一部分。在此过程中,Blogger 的前端 UI 竟然依旧弹窗提示成功,没有任何警告或错误码提示。
排查第二阶段:CSS CDATA 解析器的特殊机制
通过精准的 diff 差异对比,我们定位到了出问题的代码段位于 <b:skin> 元素的 CDATA 区域内。在这个本来用于存放纯 CSS 样式的区块里,我们有一行非常普通的 CSS 注释:
/* sess113 antigravity light hero — applies to <body class="ag-home"> only */
就是这行注释中的 <body class="ag-home">,直接导致了 Blogger SkinVariables 解析器的彻底瘫痪。从技术角度来说,XML CDATA 应当能容纳任何原始文本,但 Blogger 模板引擎的编译器为了防范潜在的 XSS 攻击,会对 CDATA 内部的代码进行二次安全扫描。一旦发现包含 <body>、<html> 或 <script> 等原始 HTML 标签标记,即使位于 CSS 注释内,编译器也会选择直接丢弃整个更新请求并进行静默拦截。
解决方案与自动校验(Lint)防御机制
解决此问题的方法非常简单:只需将注释中的原始 HTML 标签替换为自然语言说明即可:
/* applies to home body when ag-home class is set */
为了保证这一隐蔽的静默拒绝事故今后不再发生,我们在模板自动部署流水线的开头,加入了一段针对 theme.xml 自动校验的 Python 防御脚本:
import re
DANGEROUS_TOKENS = [
r'<html\b', r'<body\b', r'<head\b',
r'<script\b', r'<iframe\b',
]
def lint_skin_cdata(xml: str) -> list[str]:
skin_m = re.search(r'<b:skin>\s*<!\[CDATA\[(.*?)\]\]>\s*</b:skin>', xml, re.DOTALL)
if not skin_m: return []
css = skin_m.group(1)
findings = []
for cm in re.finditer(r'/\*.*?\*/', css, re.DOTALL):
comment = cm.group(0)
for tok in DANGEROUS_TOKENS:
if re.search(tok, comment, re.I):
findings.append(f"CSS注释中发现危险HTML标签: {tok}")
return findings
由于引入了该预校验机制,我们的自定义模板自动化部署实现了 100% 成功率,静默拒绝事故彻底归零。