识别xss风险的关键是用户输入未经净化即回写dom并被localstorage固化,形成可重复触发的dom型漏洞;需检查contenteditable内容是否原样存入localstorage、恢复时是否直接innerhtml渲染、有无过滤危险片段。

识别这类 XSS 风险,关键不是“有没有用 contenteditable”,而是看用户输入是否未经净化就回写进 DOM,且该过程绕过了服务端校验、又恰好被 localStorage 等本地存储“固化”下来——形成可重复触发的 DOM 型漏洞。
重点检查 contenteditable + localStorage 的数据流向
当页面把用户在 contenteditable 区域编辑的内容(含 HTML)存入 localStorage,再在后续加载时直接用 innerHTML 或 insertAdjacentHTML 渲染出来,就构成典型风险链。需逐环节确认:
- 用户输入是否被
localStorage.setItem('draft', el.innerHTML)类方式原样保存? - 页面初始化或恢复草稿时,是否用了
el.innerHTML = localStorage.getItem('draft')? - 是否对读出的内容做过滤?比如没调用
DOMPurify.sanitize(),也没移除<script></script>、onerror、javascript:等危险片段?
警惕“看似安全”的绕过点
有些实现会误以为“没服务端参与就不算 XSS”,但 DOM 型 XSS 不依赖后端。常见疏漏包括:
- 只过滤了
<script></script>标签,却放行了<img src="x" onerror="alert(1)">或<a href="javascript:alert(1)"></a> - 用
innerText显示内容,但渲染预览层时又切回innerHTML—— 两者不一致导致过滤失效 - 依赖
contenteditable="plaintext-only",但它仅限制浏览器默认格式操作,无法阻止用户粘贴恶意 HTML
用 Trusted Types 快速验证防护是否生效
若站点已启用 Trusted Types(现代浏览器支持),可直接检查控制台是否报错:
- 打开开发者工具 → Console,刷新页面
- 如果出现类似
Failed to set an illegal value on 'innerHTML'的错误,说明 Trusted Types 正在拦截不安全赋值,防护有效 - 若无报错,且页面能成功渲染用户存的富文本,则需人工审计
innerHTML赋值点是否接入了 Trusted Type policy
实际检测建议:模拟攻击路径验证
在测试环境手动走一遍闭环流程,比静态扫描更可靠:
- 在
contenteditable区域输入:<img src="x" onerror="alert(document.domain)"> - 点击“保存草稿”(触发
localStorage.setItem) - 刷新页面,触发草稿自动加载
- 观察是否弹窗;若弹出,说明 DOM XSS 可利用
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











