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

♫蓝月 阅读 49

我最近在学安全开发生命周期,尝试给一个简单的评论功能做威胁建模。我发现用户提交的评论内容会直接通过 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>
我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
光磊(打工版)
这绝对是个XSS风险,血泪教训啊。你现在的做法就是直接把用户输入当成HTML解析,要是有人输入恶意脚本,真的会执行。

看你的例子,<img src=x onerror=alert('xss')>这种确实会触发弹窗。浏览器遇到这种情况,会创建一个无效的图像元素,然后执行 onerror 里的脚本。

DOMPurify是必须的,我之前做过类似项目,刚开始也没用净化库,上线没多久就被发现了漏洞。这个库专门处理这种场景,能有效过滤掉危险内容。

你可以这样改:
import DOMPurify from 'dompurify';

const userInput = "<img src=x onerror=alert('xss')>";
const cleanInput = DOMPurify.sanitize(userInput);
document.getElementById('comment-list').innerHTML = cleanInput;


记住,永远不要相信用户的任何输入,哪怕看起来再无害。处理用户输入这块,谨慎为上,不然容易被坑得不轻。
点赞
2026-03-31 14:00
设计师庆敏
会执行,而且不只是 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。
点赞 5
2026-02-24 21:27