跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

如何利用 Trusted Types 重构 legacy 项目中的危险 innerHTML 赋值操作

必须配置CSP响应头Content-Security-Policy: require-trusted-types-for 'script'; trusted-types default,否则Trusted Types不生效;策略名须与createPolicy参数完全一致;innerHTML等危险API赋值需用策略包装TrustedHTML,静态HTML可暂不处理但推荐统一收口。 必须先配 CSP 响应头,否则所有 Trusted Types 代码都不起作用——浏览器根本不会拦截
innerHTML
赋值。 为什么直接加
trustedTypes.createPolicy
没反应 常见错误是只在 JS 里写策略,却没配服务端响应头。浏览器只在收到
Content-Security-Policy: require-trusted-types-for 'script'; trusted-types default
后才启用拦截机制。没这个头,
elem.innerHTML = '
照常执行,连控制台都不会报错。
trusted-types
后面的策略名(如
default
)必须和
createPolicy('default', {})
完全一致,大小写敏感,拼错就直接抛
TypeError
require-trusted-types-for 'script'
是开关,不是可选项;漏掉它,整个机制等同于不存在
对该指令无效,必须走 HTTP 响应头 开发阶段建议先用
Content-Security-Policy-Report-Only
收集违规,避免上线后大面积白屏 哪些
innerHTML
赋值必须改,哪些可以不动 不是所有
innerHTML
都要动,关键是看数据来源和上下文: 用户输入、URL 参数、API 返回的 HTML 字符串 —— 必须走策略,例如:
el.innerHTML = userInput
或
el.innerHTML = data.html
硬编码的静态 HTML(如
el.innerHTML = '
…
'
)可暂不处理,但更推荐统一收口到策略中,便于后续审计
textContent
不受 Trusted Types 管控,能用就用;它不解析 HTML,天然防 XSS
insertAdjacentText
安全,无需 TrustedHTML;但
insertAdjacentHTML
和
outerHTML
同样被拦截,需一并替换 怎么写一个安全又实用的策略函数 别在策略里手写正则过滤 HTML,既不可靠也难维护。正确做法是把净化逻辑移出策略,在外层用
DOMPurify.sanitize()
处理,再包装成
TrustedHTML
: 使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件 如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Andr​​oid友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Andr​​oid应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更 下载 立即学习 “ 前端免费学习笔记(深入) ”;
const policy = trustedTypes.createPolicy('html-sanitizer', { createHTML: (input) => { // ✅ 净化在策略外做,策略只负责“包装” return DOMPurify.sanitize(input, { RETURN_TRUSTED_TYPE: true }); } }); // 使用 el.innerHTML = policy.createHTML(userInput);
策略函数必须返回
TrustedHTML
实例,不能返回字符串,否则赋值失败 策略对象字面量里不能引用闭包变量或外部函数,否则在某些浏览器中会创建失败 避免命名策略为
default
,除非你真打算让它处理所有 HTML 场景;按用途拆分更可控,比如
comment-html
、
email-html
若策略函数抛异常(如 DOMPurify 初始化失败),
innerHTML
赋值直接中断,页面可能卡住——务必加 try/catch 并 fallback 到
textContent
legacy 项目中最容易漏掉的高危点 重构时盯着
innerHTML
很容易忽略其他等效入口:
document.write()
和
document.writeln()
同样被拦截,且无法用策略绕过,必须彻底删除或重写
location.assign(url)
若传入
javascript:
伪协议字符串,会被拦;必须用
trustedTypes.createPolicy(...).createScriptURL()
包装
DOMParser.parseFromString(html, 'text/html')
返回的
Document
中含脚本时,也会触发 Trusted Types 校验