HTML注释不是安全机制,仅是语法占位符;浏览器解析器跳过注释内容而不执行,不等于拦截恶意脚本;真正防护需依赖textContent、DOMPurify净化或CSP策略。
HTML解析器本身不扫描、不识别、也不阻断注释里的“恶意脚本”——它只按规范把<!--到-->之间所有内容当作纯文本跳过,既不解析,也不执行,更不校验安全性。
Chrome、Firefox等浏览器的HTML解析器(Blink/Gecko)在遇到<!--时,会直接进入“注释状态”,直到匹配到-->为止。中间所有内容,包括<script></script>、javascript:alert(1)、甚至嵌套的<!--,都按字符流原样吞掉,不做语法分析,不构建DOM节点,不触发任何事件。
这意味着:
<!-- <script>alert(1)</script> -->,它真不会执行——但这只是因为被跳过了,不是因为“被拦截”--><script>steal()</script><!--,浏览器会先退出注释,再解析并执行脚本这种误解常来自两个混淆点:
立即学习“前端免费学习笔记(深入)”;
<!-- <script>...</script> -->没执行,就以为“注释起了防护作用”——其实只是碰巧没被注入点利用textContent赋值)的防护效果,错误归因到HTML注释上真实防御链里,注释连“第一道防线”都算不上——它连防线都不是,只是个语法占位符。
如果你在注释里塞了脚本却没被运行,功劳不在<!--,而在以下某处:
DOMPurify.sanitize(),它会遍历整个DOM树,主动移除script标签,无论是否在注释内(注释节点本身也会被保留,但其中的脚本不会复活)script-src 'self'和禁用'unsafe-inline',导致即使脚本被意外注入并解析,也会被运行时拦截element.textContent = userHtml而非innerHTML,天然规避所有HTML解析,注释和脚本全当字符串处理注意:htmlparser2这类库的decodeEntities: true选项,也只影响实体解码行为,不会额外检查注释内容。
最易被忽略的一点:HTML注释不是沙盒,也不是过滤器。它不提供任何上下文隔离能力。一旦攻击者能控制输出拼接方式(比如模板引擎未转义变量、innerHTML直插用户数据),注释边界随时可被-->闭合绕过。
真正该做的,是让不可信数据永远不进入HTML解析流程——要么走textContent,要么经DOMPurify白名单净化,要么靠CSP兜底。指望