主题 JS 用 innerHTML 拼接评论导致存储型 XSS
现象#
某条商品评价里带 <img src=x onerror=alert(1)>,每次打开该商品都弹窗,但 Liquid 模板里搜不到这段内容。
原因#
- 评论内容由 app 存进 metafield,前端用
innerHTML把它当 HTML 插进 DOM - Liquid 端的
escape只保护模板输出,管不到 JS 运行时拼的字符串 - 主题把 JSON 塞进 data 属性后再
JSON.parse,解析结果仍可能含标签 - 没有 CSP 兜底,注入的 onerror 可以直接执行
处理步骤#
- 在主题 JS 里搜
innerHTML、insertAdjacentHTML、document.write - 纯文本场景改成
textContent或innerText,不要再拼标签 - 必须渲染富文本时先过
DOMPurify.sanitize(),再赋给节点 - 检查评论 app 的 metafield 输出,确认它是否有服务端白名单清洗
- 补一条
script-src的 CSP 作为第二道防线,并监控 violation
验收标准#
该评价在页面上显示为纯文本,Elements 里没有 img 节点,刷新不再弹窗,Console 无 CSP 之外的报错。
本文由 风格技术 技术团队整理,适用于 Shopify 标准版与 Plus 店铺。Shopify 平台能力迭代较快,具体操作路径与字段以官方文档和店铺后台实际版本为准。