加载笔记内容...
加载笔记内容...
在 React 应用中使用富文本,不可避免地要面对各种安全隐患,尤其是 XSS(跨站脚本攻击)。本文将从渲染原理、常见库对比、关键安全策略以及与其他领域的关联等角度出发,帮助你系统掌握如何在 React 环境下安全、可控地渲染富文本。
XSS 攻击
当应用允许用户输入任意 HTML 代码并将其直接渲染到页面中时,恶意的 <script>
或事件属性(如 onclick
)可能被注入,导致浏览器执行不受控的脚本,进而窃取用户信息或劫持会话。
React 中的默认保护
React 在大多数情况下会对文本进行转义,这就能避免绝大部分的 XSS 问题。但如果使用 dangerouslySetInnerHTML
来直接插入富文本,那么必须做好必要的安全过滤,否则就可能留下攻击入口。
前后端的信任边界
尽管前端可以通过各种库来过滤输入或后端返回的数据,但从安全角度看,后端也应该对接收到的富文本进行严格的筛选与存储。只有形成“前端 + 后端”双重过滤的机制,才能最大程度降低风险。
dangerouslySetInnerHTML
第三方富文本编辑器
以下是前端与后端常用的两种 HTML 过滤库,它们都能很好地防范常见的富文本 XSS 注入问题。
1import DOMPurify from 'dompurify';
2
3function SafeContent({ htmlString }) {
4 const safeHtml = DOMPurify.sanitize(htmlString);
5 return <div dangerouslySetInnerHTML={{ __html: safeHtml }} />;
6}
ALLOWED_TAGS
、ALLOWED_ATTR
等配置可实现白名单或黑名单。1import sanitizeHtml from 'sanitize-html';
2
3const cleanHtml = sanitizeHtml(dirtyHtml, {
4 allowedTags: ['b', 'i', 'strong', 'a'],
5 allowedAttributes: {
6 a: ['href', 'target']
7 }
8});
白名单策略
最常见也是较为安全的做法是白名单:只允许指定标签和少量可信属性(如链接的 href
、图片的 src
),禁止所有脚本类标签与内联事件(例如 onclick
、onload
)。
链接安全
如果允许 <a>
标签,建议强制添加 rel="noopener noreferrer"
和 target="_blank"
,以防用户打开新的页面时造成安全或性能隐患。
前后端双重过滤
保留原始内容的必要性
某些业务场景可能希望保留用户提交的“原始内容”以便后续编辑。此时可以同时存储“原始内容”和“安全过滤后内容”两份,渲染时使用后者,编辑时用前者,做到安全与功能的兼顾。
SSR 与同构应用
若你的 React 应用采用服务端渲染(SSR),考虑在服务器端也直接调用 DOMPurify(或 sanitize-html)进行过滤,输出给客户端时就已经是安全的 HTML。这样可以避免在前端再次解析与过滤,节省一定的性能开销。
网络安全与合规
安全渲染富文本不仅是技术问题,也事关用户数据安全和合规要求(如 GDPR 等)。在涉及个人信息或敏感数据时,要确保任何可能引入的第三方脚本都受控,并拥有完善的审计机制。
内容管理系统(CMS)
许多 CMS 都内置富文本编辑功能,并对用户提交内容进行预处理。如果你使用开源或商用 CMS,需要了解其默认的过滤规则,必要时可自行定制或增加前端过滤。
黑名单 vs 白名单
性能与扩展性
React 中安全地渲染富文本,最核心的思路就是“用安全过滤库清洗用户提供的 HTML”,然后再通过 dangerouslySetInnerHTML
或类似方式插入 DOM。DOMPurify 与 sanitize-html 均提供了成熟可靠的过滤逻辑,可以帮助我们便捷地对富文本进行白名单或更细粒度的安全控制。
从实际项目出发,前端与后端的双重过滤是最稳妥的做法,既能保证数据库中的数据保持安全,也能在展示给用户之前进行再次校验。结合对链接与事件属性等细节的限制,就能最大程度上避免 XSS 等常见攻击,为用户提供安全的富文本体验。