P183 · 安全与权限

转义不可信内容中的标记

Untrusted-Content-as-Markup Escaping

显示外部内容前转义 HTML 等标记,避免被当成页面代码执行。

编辑审核

以下示例与示意结果由本站编写,用于说明方法,不是模型实测结果。

使用场景

生成HTML报告显示外部PR标题,教学标题包含 <script> 标记和 </script> 终止片段。文本节点与嵌入JSON脚本是不同接收上下文,需要各自编码。

具体做法

标出每个不可信值进入文本、属性、URL或脚本的位置。可见纯文本优先textContent或模板自动转义;属性与URL用相应契约校验/编码。JSON用库序列化,并按成熟渲染器的安全嵌入方式处理<与脚本终止,不能只做HTML转义。需要展示HTML用受约束容器,与允许执行不同。测试实际最终DOM。

反例

title直接拼<h1>和JavaScript字符串,统一HTML转义就称所有上下文安全。

改进写法

PR标题作textContent显示,不通过innerHTML解释。嵌入状态使用支持的安全JSON helper并处理脚本终止;测试含</script>和引号的教学标题作为数据还原,不执行新标记。分别验证属性与URL,不套一个通用净化函数。

为什么这样改

不同解析器赋予相同字符不同含义。上下文编码让外部数据留作数据,防文本进入HTML或脚本语法后获得执行意义。

如何验证

教学页面可见标题保留字面标记;DOM无由标题新增的脚本,测试哨兵未执行。嵌入JSON解析后值相同且 <script> 元素边界未被截断。仅看到显示正常不能证明所有插入位置安全。

适用边界

编码不替代授权、URL目标限制或完整XSS防线;允许富文本需独立净化契约。JSON.stringify本身不保证安全嵌入HTML脚本,也不是shell转义。冻结报告CSP只约束其场景,不能直接套所有页面。

原文与版本

如何收录这些方法

相关方法