前端渲染用户输入时如何防止 XSS 攻击?

东方雨橙 阅读 38

我在做一个评论功能,用户提交的内容直接用 innerHTML 插到页面上,结果发现如果用户输入带 script 标签的内容,会被执行!这明显有 XSS 风险。我试过用 DOMPurify,但项目不允许引入第三方库,只能自己处理。

现在想手动做输出转义,但不确定哪些字符必须转。比如下面这段代码:

const userInput = '<img src=x onerror=alert(1)>';
commentDiv.innerHTML = userInput; // 危险!

有没有简单又安全的原生 JS 方法,能把用户输入里的特殊字符转成 HTML 实体再插入?

我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
峻豪~
峻豪~ Lv1
防止XSS攻击的关键在于确保用户输入不会被当作代码执行。你提到的情况正是典型的XSS漏洞,因为直接使用innerHTML插入了用户输入的内容。我们可以通过将特殊字符转换为HTML实体来避免这个问题。

原理是这样:HTML实体是一种在HTML文档中表示特殊字符的方法。例如,小于号<可以用<代替,大于号>可以用>代替。这样浏览器会将这些实体当作普通文本处理,而不是代码的一部分。

为了手动实现输出转义,我们需要将一些特定的字符转换为对应的HTML实体。通常需要转义的字符包括:< > " ' &。

下面是简单的JavaScript函数,可以将这些字符转义为HTML实体:

function escapeHtml(unsafe) {
// 创建一个空的DOM元素
var temp = document.createElement('div');
// 将用户输入设置为文本节点
temp.textContent = unsafe;
// 返回转义后的字符串
return temp.innerHTML;
}

// 使用示例
const userInput = '';
const safeInput = escapeHtml(userInput);
commentDiv.innerHTML = safeInput; // 现在是安全的


这个函数的工作原理是利用浏览器的自动转义机制。当你把一段文本设置为DOM元素的textContent属性时,浏览器会自动将其中的特殊字符转义。然后我们读取该元素的innerHTML属性,得到的就是已经转义过的字符串,可以直接插入到页面中而不用担心XSS攻击。

这样做不仅简单,而且效果可靠。虽然看起来有点绕弯,但实际上利用了浏览器内置的安全特性,避免了手动编写复杂的转义逻辑。希望这个方法能帮到你。
点赞
2026-03-22 22:24
UX-熙研
UX-熙研 Lv1
这个问题很常见,innerHTML 直接插用户输入就是典型的 XSS 漏洞。

最直接的解决办法是写一个转义函数,把那些会破坏 HTML 的字符替换成实体:

function escapeHtml(text) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return text.replace(/[&<>"']/g, m => map[m]);
}

// 使用
commentDiv.innerHTML = escapeHtml(userInput);


不过说实话,如果你只是想把用户输入显示出来,更省心的办法是用 textContent

commentDiv.textContent = userInput;


这样浏览器根本不会把内容当作 HTML 解析,