事情本身不复杂,线索都在日志里。知识库文档从后台富文本导入,chunk 里带了 img 标签的 onerror 事件,答案把原文片段拼进 HTML 返回,前端用 v-html 渲染后控制台报错,安全扫描直接标了 XSS。
第一反应是「后端返回的引用字段没有转义」,验证下来不成立。
真正麻烦的地方在于,几个原因的现象几乎一样。富文本入库前没有做清洗。少数情况下是引用展示直接用了 v-html。
另外,历史 chunk 里已经存了带事件的标签。
扫一遍现有 chunk 里的事件属性
python -c "import re;s=open('chunk.html',encoding='utf-8').read();print(re.findall(r'on\w+=',s))"
入库前用 bleach 只放行白名单标签
python -c "import bleach;print(bleach.clean('<img src=x onerror=alert(1)>',tags=['b','i'],attributes={}))"
前端改成文本插值,不再拼 HTML
python -c "print('use textContent instead of innerHTML')"
等前面都确认过,再对存量数据跑一遍清洗并回写
python clean_chunks.py --collection docs --dry-run
改完先别撤,确认这几项。扫描结果里不再出现事件属性,引用块正常显示纯文本,前端控制台没有报错。
提醒一点。引用内容本质上来自不可信输入,展示层一律按纯文本处理,需要富文本时走白名单清洗。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
