React组件直接渲染URL参数时如何防范DOM型XSS攻击?
我在做搜索功能时遇到个问题,用户输入的搜索词会通过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漏洞呢?
首先你要明白为什么会出现这个XSS漏洞。你现在的代码用了
dangerouslySetInnerHTML,这个方法本质上就是直接把HTML字符串插入到DOM里,React不会对它做任何转义或过滤。如果你从URL参数里拿到的内容是恶意脚本,比如<script>alert(1)</script>,那么这段脚本就会被直接执行,这就导致了XSS攻击。要解决这个问题,其实不用想得太复杂,核心原则就是:永远不要信任用户输入。即使是从URL参数来的数据,也必须进行严格的处理。具体做法如下:
第一步,去掉
dangerouslySetInnerHTML,这是个危险的操作,99%的情况下都不需要用它。React默认的渲染方式是安全的,它会自动对内容进行转义。比如说,如果你直接把字符串渲染到JSX里,React会自动把<和>转义成HTML实体,这样就不会被执行为HTML标签了。第二步,修改你的代码,改成安全的方式渲染。下面是改好的代码:
这里的关键点是,直接用
{query}把变量插进去,React会自动帮你转义特殊字符,比如<、>和&,所以就算用户输入了恶意脚本,它也会被当成普通文本显示,而不会被执行。第三步,如果你想进一步增强安全性,可以在获取到
query的时候做一次额外的校验和清理。虽然React已经帮你做了转义,但主动防御总是好的。可以用一个简单的正则表达式或者第三方库来过滤掉明显有问题的内容。比如:这里的
sanitizeInput函数用了一个简单的正则表达式,把所有的HTML标签都移除了。当然,你也可以用更专业的库,比如DOMPurify,它能帮你更全面地清理不安全的内容。最后总结一下:React默认的渲染方式是安全的,只要你不使用
dangerouslySetInnerHTML,基本上就能避免大部分XSS问题。如果你还想更保险,可以加一层输入清理逻辑。记住,前端的安全防护永远是多层的,不能依赖单一措施。希望这些解释对你有帮助,有问题随时问。