用户发的弹幕里带 <img src=x onerror=alert(document.cookie)>,页面用 innerHTML 插入,刷新后脚本真的执行了。碰到这种情况,我一般先确认改动有没有真的生效。
原因不复杂,弹幕渲染为了保留颜色和表情直接拼 HTML,用户输入没有转义。后端只过滤了长度,没有处理标签,CSP 里还留着 unsafe-inline。
「弹幕 XSS」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。改完顺手把文档补一句,省得下次自己重新推一遍。
const div = document.createElement('div');
div.textContent = msg.text; // 不拼 HTML
track.appendChild(div);
监控和日志的时间要对上,时区不一致会多绕很大一圈。临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。
动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。
具体做法是,渲染改用 textContent 或者先做转义;需要颜色时只放行白名单标签 用 DOMParser 过滤;CSP 去掉 unsafe-inline 并上报违规。
最后用这个标准收尾,再发一条带 img onerror 的弹幕,页面只显示原文,控制台没有脚本执行。
