Trusted Types 不能彻底重构异步字符串拼接逻辑,但能强制所有异步路径中落入 DOM sink 的字符串必须经校验为 TrustedHTML 或 TrustedScriptURL;需后端配置 CSP 响应头 require-trusted-types-for 'script' 并匹配策略名 default,前端调用须统一包装,禁用万能策略,按场景分权隔离,并验证拦截生效。

Trusted Types 不能“彻底重构”异步字符串拼接逻辑本身,但它能强制将所有异步路径中最终落入 DOM sink 的字符串,转为必须经类型校验的 TrustedHTML 或 TrustedScriptURL 实例——前提是整个链路从服务端 CSP 到前端调用全部对齐。
必须先配好 CSP 响应头,否则所有 JS 策略无效
浏览器只在收到正确 HTTP 头后才拦截非法赋值。仅前端写 trustedTypes.createPolicy 不起作用:
- 生产环境必需头:
Content-Security-Policy: require-trusted-types-for 'script'; trusted-types default -
default是强制策略名,JS 中创建策略时名称必须完全一致,否则抛TypeError,不降级 -
<meta http-equiv="Content-Security-Policy">不支持require-trusted-types-for,必须由后端、Nginx 或 CDN 配置响应头 - 开发阶段可用
Content-Security-Policy-Report-Only先收集违规日志,避免上线即阻断
识别并拦截异步流程中所有逃逸点
异步逻辑(如 fetch 后拼接 HTML、Promise.then 中插入模板)常在回调里直写 innerHTML,这些是高危盲区:
-
el.innerHTML = await getTemplate()→ 必须改为el.setHTML(policy.createHTML(await getTemplate())) -
insertAdjacentHTML('beforeend', html)同样受控,需统一走策略包装 -
location.href = await getRedirectUrl()→ 必须用policy.createURL(await getRedirectUrl()) -
iframe.srcdoc = unsafeHtml→ 需传policy.createHTML(unsafeHtml) - 注意
DOMParser.parseFromString(html, 'text/html')若含脚本,也会触发 Trusted Types 校验
按异步场景拆分最小权限策略,拒绝万能构造器
不要用一个 createHTML: s => s 策略兜底,这等于没开。应按数据来源和用途隔离:
- 富文本渲染(如 Markdown 输出):集成
DOMPurify.sanitize后再 wrap 成TrustedHTML - 服务端模板(如 Handlebars 渲染结果):策略只接受已知安全的模板输出,禁止用户输入直传
- 动态组件加载(如
import('./widget.js').then(...)后插入 HTML):策略应限定允许的标签(如div、span),禁用script、onerror等 - 第三方库调用(如 jQuery
.html()):确认其是否自动识别TrustedHTML;未适配的需封装代理层
验证异步链路是否真正受控
上线前必须确认两点:
- 所有异步回调中的
innerHTML、insertAdjacentHTML、location.assign等调用,均已替换为策略包装后的可信对象 - CSP 响应头已生效(可在 DevTools → Application → Manifest 或 Network → Response Headers 中验证)
- 用真实用户流触发异步操作,观察控制台是否出现
TypeError: Failed to set an illegal value—— 出现说明拦截生效,未出现说明仍有漏网路径










