React组件直接渲染用户输入导致XSS漏洞,修复后为何仍被漏洞赏金计划标记?

UI诗晴 阅读 4

我在处理用户评论展示功能时,直接用dangerouslySetInnerHTML渲染了后端返回的内容,后来在漏洞赏金测试中被指出存在XSS漏洞。

虽然我已经改用DOMPurify清理内容,但测试时还是能注入脚本,这到底是哪里没处理到位?


import DOMPurify from 'dompurify';

function Comment({ content }) {
  const sanitized = DOMPurify.sanitize(content); // 尝试了净化处理
  return (
    <div>
      {sanitized} {/* 直接输出净化后的HTML */}
      {/* 测试时输入alert(1)仍能触发弹窗 */}
    </div>
  );
}

export default Comment;

难道不应该用文本转义的方式?或者DOMPurify的配置有问题?其他同事说应该用React的内置机制处理…

我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
百里诗语
问题出在你直接把 DOMPurify.sanitize 返回的 HTML 字符串塞进了 JSX 里,但没有正确处理它。React 默认会转义所有插入 JSX 的内容,防止 XSS 攻击。而你用了 dangerouslySetInnerHTML 这个 API,相当于绕过了 React 的安全机制。

虽然你加了 DOMPurify 做净化,但如果配置不当或者环境有问题,还是可能被绕过。最靠谱的做法是避免直接渲染 HTML,除非你非常确定内容是安全的。

修复方案其实很简单,别用 dangerouslySetInnerHTML,而是直接用 React 的内置机制渲染纯文本。代码可以改成这样:

function Comment({ content }) {
return (
<div>
{content} {/* React 会自动转义特殊字符 */}
</div>
);
}

export default Comment;


如果你确实需要支持富文本(比如加粗、链接这种),可以用 DOMPurify 配合 dangerouslySetInnerHTML,但要确保配置正确。比如这样:

import DOMPurify from 'dompurify';

function Comment({ content }) {
const sanitized = DOMPurify.sanitize(content, { USE_PROFILES: { html: true } });
return (
<div
dangerouslySetInnerHTML={{ __html: sanitized }}
/>
);
}

export default Comment;


这里的关键点有两个:
1. DOMPurify 的配置要用 USE_PROFILES,限制只允许安全的 HTML 标签和属性。
2. 确保你的项目运行在现代浏览器环境下,因为 DOMPurify 在老旧浏览器中可能存在兼容性问题。

最后提醒一句,XSS 防护不只是前端的事,后端也要对用户输入做校验和过滤。前后端都做好防护才是真正的双保险。
点赞 1
2026-02-18 15:12