React中用dangerouslySetInnerHTML怎么防XSS攻击?

一振莉 阅读 2

我在做一个富文本展示功能,后端返回的HTML字符串需要直接渲染,用了dangerouslySetInnerHTML,但担心XSS漏洞。试过自己写正则过滤script标签,但好像还是有风险,比如img的onerror也能执行JS。有没有靠谱又不重的方案?

现在代码大概是这样:

const sanitizedHtml = rawHtml.replace(/<scriptb[^<]*(?:(?!</script>)<[^<]*)*</script>/gi, '');
return <div dangerouslySetInnerHTML={{ __html: sanitizedHtml }} />;

但听说这种黑名单方式根本防不住,是不是得用DOMPurify这类库?引入它会不会太重?

我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
博主绍轩
你担心得对,正则过滤确实不靠谱。XSS攻击的花样太多了,script标签只是最基础的,img的onerror、svg的onload、a标签的javascript:协议、style标签里的expression等等,黑名单根本列不完,分分钟被绕过。

DOMPurify是目前最靠谱的方案,React项目里几乎标配。这货核心代码就十几KB,只干清理HTML这一件事,比自己写过滤逻辑安全得多。

用法很简单:

先装一下:
npm install dompurify


然后这样用:
import DOMPurify from 'dompurify';

const sanitizedHtml = DOMPurify.sanitize(rawHtml);

return
;


DOMPurify默认会清理掉所有script、事件属性、javascript:协议这些危险内容。如果你需要保留某些标签(比如a、img),可以这样配置:
const sanitizedHtml = DOMPurify.sanitize(rawHtml, {
ALLOWED_TAGS: ['p', 'br', 'b', 'i', 'a', 'img'],
ALLOWED_ATTR: ['href', 'src', 'alt']
});


关于"重不重"的问题,我觉得想多了。十几KB对现代前端项目来说根本不算啥,而且这是安全相关的代码,省不得。你要是实在纠结,可以按需引入,不过收益有限。

总之,别自己写正则过滤了,上DOMPurify完事儿。
点赞 1
2026-03-14 13:05