前端做威胁建模时,用户输入直接渲染到页面会不会有XSS风险?

♫蓝月 阅读 15

我最近在学安全开发生命周期,尝试给一个简单的评论功能做威胁建模。我发现用户提交的评论内容会直接通过 innerHTML 插入到页面里,虽然现在只是本地测试,但总觉得这样不安全。我试过用 DOMPurify 清洗,但不确定是不是必须的?

比如下面这段代码,如果用户输入了 <script>alert(1)</script>,会不会真的执行?

<div id="comment-list"></div>
<script>
  const userInput = "<img src=x onerror=alert('xss')>";
  document.getElementById('comment-list').innerHTML = userInput;
</script>
我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
设计师庆敏
会执行,而且不只是 alert(1) 这种 harmless 的情况,攻击者可以偷 cookie、劫持会话、构造钓鱼表单,甚至静默跳转到恶意网站。innerHTML 本质上是「直接解析 HTML 字符串」,浏览器不区分“你是开发者还是用户”,只要字符串里有可执行的标签或事件,它就照单全收。

你贴的代码里用了 ,onerror 是标准事件处理器,浏览器加载失败时立刻触发 JS,完全绕过 script 标签——所以 DOMPurify 不是“可选”,是必须加一层防线,尤其当内容来自用户输入时。

不过也有更干净的做法:如果只是展示文本,别用 innerHTML,改用 textContent 或 innerText,浏览器会自动转义 <、>、& 等字符,XSS 就直接没了。比如:

const userInput = "";
const container = document.getElementById('comment-list');
container.textContent = userInput; // 这样就安全了


但如果评论里确实要支持富文本(比如加粗、链接),那就得用 DOMPurify 做清洗,而且最好配合 CSP(Content-Security-Policy)做纵深防御。比如:

const cleanHTML = DOMPurify.sanitize(userInput, { ALLOWED_TAGS: ['b', 'i', 'a', 'br'] });
container.innerHTML = cleanHTML;


记住一句话:只要内容不是你亲手写的字符串,就别直接塞进 innerHTML。本地测试也别侥幸——你永远不知道哪天漏了个 onerror 或 onmouseover。
点赞 1
2026-02-24 21:27