前端渲染用户输入时如何防止 XSS 攻击?
我在做一个评论功能,用户提交的内容直接用 innerHTML 插到页面上,结果发现如果用户输入带 script 标签的内容,会被执行!这明显有 XSS 风险。我试过用 DOMPurify,但项目不允许引入第三方库,只能自己处理。
现在想手动做输出转义,但不确定哪些字符必须转。比如下面这段代码:
const userInput = '<img src=x onerror=alert(1)>';
commentDiv.innerHTML = userInput; // 危险!
有没有简单又安全的原生 JS 方法,能把用户输入里的特殊字符转成 HTML 实体再插入?
原理是这样:HTML实体是一种在HTML文档中表示特殊字符的方法。例如,小于号
<可以用<代替,大于号>可以用>代替。这样浏览器会将这些实体当作普通文本处理,而不是代码的一部分。为了手动实现输出转义,我们需要将一些特定的字符转换为对应的HTML实体。通常需要转义的字符包括:< > " ' &。
下面是简单的JavaScript函数,可以将这些字符转义为HTML实体:
这个函数的工作原理是利用浏览器的自动转义机制。当你把一段文本设置为DOM元素的
textContent属性时,浏览器会自动将其中的特殊字符转义。然后我们读取该元素的innerHTML属性,得到的就是已经转义过的字符串,可以直接插入到页面中而不用担心XSS攻击。这样做不仅简单,而且效果可靠。虽然看起来有点绕弯,但实际上利用了浏览器内置的安全特性,避免了手动编写复杂的转义逻辑。希望这个方法能帮到你。
最直接的解决办法是写一个转义函数,把那些会破坏 HTML 的字符替换成实体:
不过说实话,如果你只是想把用户输入显示出来,更省心的办法是用
textContent:这样浏览器根本不会把内容当作 HTML 解析,
标签啥的直接就当成普通文本显示了,天然免疫 XSS。textContent适合大多数场景,除非你确实需要支持用户输入富文本(加粗啊、链接啊之类的),那才需要用 innerHTML + 转义,或者更复杂的白名单过滤。你那个例子里的
<img src=x onerror=alert(1)>经过转义后会变成<img src=x onerror=alert(1)>,浏览器会当作普通文本显示,不会执行。