HTML应用漏洞本质是渲染逻辑中信任HTML内容引发的安全问题,核心风险在于innerHTML误用、URL属性协议失控及服务端与前端双渲染时转义责任不清。

HTML 应用本身不执行逻辑,所谓“HTML 应用漏洞”实际是前端渲染逻辑、服务端输出控制、或混合渲染场景中因信任 HTML 内容引发的安全问题。直接在纯 index.html 里找漏洞没意义,关键看它怎么被用。
为什么 innerHTML 是最常被误用的高危操作
浏览器不会校验你塞进去的字符串是不是“安全 HTML”,只要语法合法,script、onerror、javascript: 伪协议全都会执行。
常见错误现象:
- 用户昵称显示处用了
el.innerHTML = userInput,结果输入<img src=1 onerror=alert(1)>弹窗 - 后台富文本编辑器导出的 HTML 被直接
document.write()渲染,嵌入了远程脚本
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 永远优先用
textContent或innerText渲染纯文本内容 - 必须插入 HTML 时,用成熟库如
DOMPurify.sanitize()过滤,而不是自己写正则 - 禁止把用户输入拼接到
javascript:、data:text/html、iframe srcdoc等执行上下文中
src、href、form.action 的协议白名单控制
这些属性看似只加载资源,但若未校验值,就可能触发 XSS 或 SSRF。比如:<a href="javascript:alert(1)"> 或 <img src="data:image/svg+xml,<svg xmlns=...>">。
使用场景:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 评论区允许用户填个人主页链接
- 后台配置跳转地址(如登录后 redirect_url)
- 表单提交目标动态生成(
form.action = userControlledUrl)
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 对所有可由用户控制的 URL 类型属性,强制校验协议头:只允许
https://、http://、//(相对协议)、/(绝对路径) - 拒绝
javascript:、vbscript:、data:、file:、blob: - 用
URL构造函数做基础解析,再检查url.protocol,比正则更可靠
服务端模板与前端框架的“双渲染”陷阱
当服务端用 Thymeleaf / Jinja2 渲染一次,前端又用 Vue / React 再 render 一次,容易绕过服务端的 HTML 编码。
典型错误:
- 服务端输出:
<div v-html="userContent"></div>,而userContent是已编码过的字符串(如<script></script>),Vue 却把它当原始 HTML 解析,结果解码后仍执行 - PHP 中
echo htmlspecialchars($input, ENT_QUOTES)后,又被 JS 拿去innerHTML,双重编码导致显示异常,开发者为“修复显示”又去掉服务端编码
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 明确渲染责任边界:服务端输出 → 前端只做纯文本插值;或前端接管全部渲染 → 服务端返回 JSON,不输出任何 HTML 片段
- 禁用框架的
v-html/dangerouslySetInnerHTML,除非你 100% 控制其来源且已用DOMPurify处理 - 若必须混合,确保服务端和前端使用同一套编码/解码规则,并在接口文档中标明字段是否“已 HTML 编码”
真正难防的不是某个标签或属性,而是开发过程中对“谁负责转义”“在哪一层解码”的模糊认知。一个 innerHTML 调用背后,可能牵扯服务端模板配置、API 字段语义定义、前端组件封装粒度——漏洞往往藏在这些层之间没对齐的地方。


















