必须通过http响应头启用trusted types才能拦截innerhtml等dom sink,仅js创建策略无效;关键头为content-security-policy: require-trusted-types-for 'script'; trusted-types default,且default策略名不可省略。

仅靠 JS 里调用 TrustedTypes.createPolicy() 无法杜绝 innerHTML 引发的 DOM XSS。真正起作用的是服务端必须返回正确的 CSP 响应头,浏览器据此开启运行时拦截——没这个头,策略函数再规范也形同虚设。
必须配置的 CSP 响应头
这是强制启用 Trusted Types 的唯一有效方式,不能用 标签替代:
Content-Security-Policy: require-trusted-types-for 'script'; trusted-types default;-
require-trusted-types-for 'script'表示所有可能执行脚本的 DOM sink(包括 innerHTML)都必须传入 Trusted 类型 -
trusted-types default中的 default 是必需的策略名,否则TrustedHTML构造失败时直接抛错,不降级 - 开发阶段可用
Content-Security-Policy-Report-Only先收集违规,再上线强制模式
哪些 innerHTML 赋值会被拦截?
拦截只发生在明确写入 innerHTML 的时刻,且仅当值不是 TrustedHTML 实例:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
-
el.innerHTML = '<b>ok</b><script>alert(1)</script>';→ 触发TypeError -
el.innerHTML = policy.createHTML('<b>ok</b>');→ 正常执行 -
el.outerHTML、insertAdjacentHTML同样受控;但textContent、setAttribute不在拦截范围内 - 框架内部间接调用(如 React 的
dangerouslySetInnerHTML)是否被拦,取决于框架是否适配 Trusted Types
如何安全创建和使用 HTML 策略
策略不是“万能过滤器”,而是职责清晰的封装逻辑:
- 不要用一个策略处理所有场景,比如把富文本、用户昵称、评论内容混在一起净化
- 推荐用 DOMPurify 配合策略:
createHTML: (input) => DOMPurify.sanitize(input, { RETURN_TRUSTED_TYPE: true }) - 避免手动拼接 HTML 字符串后再传入策略,应在构造前就完成结构化组装
- 策略名要显式声明在 CSP 的
trusted-types列表中,否则浏览器拒绝使用
常见失效原因
很多项目启用了 API 却没防住 XSS,问题往往出在这些细节:
- 服务端没返回 CSP 头,或头写在 meta 标签里(无效)
- 策略名和 CSP 中声明的不一致,比如策略叫
htmlPolicy,但 CSP 写的是trusted-types default却没加htmlPolicy - 代码中仍存在绕过策略的写法,例如
eval('...')、setTimeout(string)、location.href = 'javascript:...' - 第三方库或框架未适配 Trusted Types,自行调用 innerHTML 且未走策略
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










