React中如何防止使用window.location.search导致的DOM型XSS?

东方爱菊 阅读 31

我在React组件里用URL参数显示用户输入,发现这样写可能有XSS漏洞:


function SearchResults() {
  const searchParam = new URLSearchParams(window.location.search).get('q') || '';
  return (
    

您搜索的内容是:

); }

虽然用了DOMPurify.clean(window.location.href)尝试净化,但测试时输入alert(1)依然会触发弹窗。难道不能直接操作innerHTML?有没有更安全的React原生写法?

我来解答 赞 7 收藏
二维码
手机扫码查看
1 条解答
司徒子源
你说的这个问题确实挺常见的,直接操作 innerHTML 确实很容易踩坑,尤其是React这种框架里更推荐用受控的方式处理用户输入。

先说结论:别用 innerHTML!React本身已经提供了更安全的写法,比如直接用JSX渲染或者 dangerouslySetInnerHTML 配合净化库。你的代码问题在于虽然用了 DOMPurify,但可能没正确嵌套到JSX渲染里。

试试这样改:

import DOMPurify from 'dompurify';

function SearchResults() {
const searchParam = new URLSearchParams(window.location.search).get('q') || '';
const sanitizedParam = DOMPurify.sanitize(searchParam); // 先净化

return (
<div>
您搜索的内容是:
<span>{sanitizedParam}</span> {/* 直接插值渲染,避免innerHTML */}
</div>
);
}


关键是这里用 DOMPurify.sanitize 处理完后,直接在 {} 插值渲染,而不是搞什么 innerHTML。React会自动对插值内容进行转义,所以比手动操作 innerHTML 安全得多。

如果你非要动态插入HTML(不推荐),可以用这种方式:

return (
<div>
您搜索的内容是:
<span dangerouslySetInnerHTML={{ __html: sanitizedParam }} />
</div>
);


不过说实话,能不用 dangerouslySetInnerHTML 就别用,太容易出问题了。像你这种场景直接插值就挺好,简单又安全。

最后提醒一下,XSS这玩意儿防不胜防,前端净化只是第一步,数据库层面存储用户输入时最好也做下基本过滤,双保险总是好的。
点赞 11
2026-01-31 12:00