You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用模板字面量渲染页面时如何防范HTML注入?

核心解决思路

这类问题属于典型的HTML注入(XSS)风险,本质是不可信的用户输入被传入了会解析HTML的API。不存在“使用模板字面量就必须搭配innerHTML”的说法,模板字面量只是ES标准的字符串语法,和内容插入的API没有绑定关系,风险和模板字面量本身无关,完全可以通过合理选择API规避,具体方案分场景选择:

1. 纯文本场景优先用安全DOM API,从根源规避解析

插入纯用户文本时,优先使用textContent属性赋值,浏览器会自动将所有内容作为纯文本处理,不会解析任何HTML标签,完全不存在注入风险。
对应问题中的代码,两种常见安全写法:
第一种是纯DOM创建,全程不拼接含用户输入的HTML字符串:

const userInput = prompt("Enter your name", "<b>foo</b>");

// 创建DOM节点
const li = document.createElement('li');
// 用户输入直接赋值给textContent,<b>标签会原样显示为文本,不会渲染粗体
li.textContent = userInput;
const ul = document.createElement('ul');
ul.append(li);
const container = document.createElement('div');
container.append(ul);
document.body.append(container);

第二种是固定结构用innerHTML渲染,用户输入单独赋值到预留插槽:

const userInput = prompt("Enter your name", "<b>foo</b>");
// 先渲染不含用户输入的固定结构
document.body.innerHTML = `
  <div>
    <ul>
      <li class="username-slot"></li>
    </ul>
  </div>
`;
// 单独给内容插槽赋值文本,用户输入不会接触HTML解析流程
document.querySelector('.username-slot').textContent = userInput;

2. 必须拼接HTML字符串时,先做严格转义

如果业务场景必须将用户内容拼接进HTML字符串再传入innerHTML,必须先对用户输入做HTML实体转义,将触发HTML解析的特殊字符替换为不会被解析的字符实体,需要转义的核心字符包括:

  • & → &amp;
  • < → &lt;
  • > → &gt;
  • " → &quot;
  • ' → &#39;

可以利用浏览器原生能力实现轻量转义,比手写正则更可靠,不会漏过特殊字符:

function escapeHTML(unsafeStr) {
  const tempEl = document.createElement('div');
  tempEl.textContent = unsafeStr;
  return tempEl.innerHTML;
}

// 使用时先转义用户输入,再拼进模板
const userInput = prompt("Enter your name", "<b>foo</b>");
document.body.innerHTML = `
  <div>
    <ul>
      <li>${escapeHTML(userInput)}</li>
    </ul>
  </div>
`;

注意:上述转义仅适用于将用户内容插入到HTML标签的文本位置,如果要将用户输入插入到HTML属性、事件回调、script/style标签内,需要对应场景的额外转义规则,不能直接套用这个方法。

最佳实践提醒

  • 永远不要把未转义的用户可控内容传入innerHTML、outerHTML、document.write这类会解析HTML的API。
  • 不要自己写正则过滤HTML标签,这类规则很容易被变形的注入payload绕过,纯文本场景优先用textContent。
  • 如果业务需要渲染用户提交的富文本,不要自己实现过滤逻辑,直接使用经过社区长期安全审计的HTML净化库,只保留白名单内的安全标签和属性。

内容的提问来源于stack exchange,提问作者Khaled

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 11:03:23