React组件直接渲染URL参数时如何防范DOM型XSS攻击?

迷人的翌萌 阅读 39

我在做搜索功能时遇到个问题,用户输入的搜索词会通过URL参数保存,然后用React组件显示出来。但测试时发现如果在地址栏输入类似search?query=<script>alert(1)</script>,页面真的会弹窗了。代码是这样写的:


function Search() {
  const query = new URLSearchParams(window.location.search).get('query');
  return (
    <div>
      当前搜索词:<div dangerouslySetInnerHTML={{ __html: query }} />
    </div>
  );
}

我试过用htmlspecialchars转义但React里没这个方法,也尝试过替换<script>标签但感觉治标不治本。这种直接渲染URL参数的场景该怎么彻底解决XSS漏洞呢?

我来解答 赞 7 收藏
二维码
手机扫码查看
2 条解答
Des.蒙蒙
这个问题确实是个典型的安全隐患。直接将用户输入的内容通过dangerouslySetInnerHTML插入到DOM中,很容易导致XSS攻击。正确的做法是避免使用dangerouslySetInnerHTML,而是将用户输入的内容作为普通文本处理。

你可以通过React的特性来安全地渲染用户输入的内容。具体来说,就是不使用dangerouslySetInnerHTML,直接将query变量插入到JSX中,这样React会自动对HTML进行转义。

修改后的代码如下:

function Search() {
const query = new URLSearchParams(window.location.search).get('query');
return (

当前搜索词:{query}

);
}


这样做,React会自动将query中的特殊字符进行转义,从而防止XSS攻击。如果确实需要保留一些HTML标签(比如加粗、斜体等),那得考虑使用白名单机制来过滤掉不安全的标签和属性,而不是简单的替换或转义,这样也能提高安全性。

另外,建议在服务端也进行类似的验证和过滤,双重保障嘛。毕竟客户端的安全措施可以被绕过,服务端的检查才是最可靠的防线。
点赞
2026-03-20 20:07
小瑞珺
小瑞珺 Lv1
这个问题确实很典型,很多新手在用React的时候都会踩这个坑。咱们一步步来说怎么解决。

首先你要明白为什么会出现这个XSS漏洞。你现在的代码用了 dangerouslySetInnerHTML,这个方法本质上就是直接把HTML字符串插入到DOM里,React不会对它做任何转义或过滤。如果你从URL参数里拿到的内容是恶意脚本,比如 <script>alert(1)</script>,那么这段脚本就会被直接执行,这就导致了XSS攻击。

要解决这个问题,其实不用想得太复杂,核心原则就是:永远不要信任用户输入。即使是从URL参数来的数据,也必须进行严格的处理。具体做法如下:

第一步,去掉 dangerouslySetInnerHTML,这是个危险的操作,99%的情况下都不需要用它。React默认的渲染方式是安全的,它会自动对内容进行转义。比如说,如果你直接把字符串渲染到JSX里,React会自动把 <> 转义成HTML实体,这样就不会被执行为HTML标签了。

第二步,修改你的代码,改成安全的方式渲染。下面是改好的代码:


function Search() {
// 从URL参数中获取query值
const query = new URLSearchParams(window.location.search).get('query') || '';

return (
<div>
当前搜索词:{query}
</div>
);
}


这里的关键点是,直接用 {query} 把变量插进去,React会自动帮你转义特殊字符,比如 <>&,所以就算用户输入了恶意脚本,它也会被当成普通文本显示,而不会被执行。

第三步,如果你想进一步增强安全性,可以在获取到 query 的时候做一次额外的校验和清理。虽然React已经帮你做了转义,但主动防御总是好的。可以用一个简单的正则表达式或者第三方库来过滤掉明显有问题的内容。比如:


function sanitizeInput(input) {
// 移除所有HTML标签,只保留纯文本
return input.replace(/<[^>]*>/g, '');
}

function Search() {
const rawQuery = new URLSearchParams(window.location.search).get('query') || '';
const query = sanitizeInput(rawQuery); // 清理输入

return (
<div>
当前搜索词:{query}
</div>
);
}


这里的 sanitizeInput 函数用了一个简单的正则表达式,把所有的HTML标签都移除了。当然,你也可以用更专业的库,比如 DOMPurify,它能帮你更全面地清理不安全的内容。

最后总结一下:React默认的渲染方式是安全的,只要你不使用 dangerouslySetInnerHTML,基本上就能避免大部分XSS问题。如果你还想更保险,可以加一层输入清理逻辑。记住,前端的安全防护永远是多层的,不能依赖单一措施。

希望这些解释对你有帮助,有问题随时问。
点赞 6
2026-02-19 13:05