XSS 的修复视角
XSS 的根因是把不可信数据放进了会被解释执行的上下文,修复的关键是按输出位置选择对应的编码规则:HTML 正文、属性值、脚本内部、URL 参数各自不同,用一种通用编码覆盖全部上下文仍会留下注入点。配合内容安全策略与框架默认转义,可以显著降低残余风险。
基本信息
| 编码原则 | 按输出上下文选择实体编码规则 |
|---|---|
| 富文本 | 走白名单过滤,不允许任意标签与属性 |
| 内容安全策略 | 收紧脚本来源,避免放行内联脚本 |
| 框架用法 | 使用模板引擎默认转义,禁用原始 HTML 渲染开关 |
| 常见误区 | 自写正则做黑名单过滤,容易漏掉变体 |
典型使用场景
- 用户昵称、评论、站内信等回显内容的编码处理
- 查询参数回显在页面标题与面包屑中
- JSON 数据内嵌到脚本上下文时的序列化处理
- 跳转链接参数与图片地址的属性值编码
- 富文本编辑器内容的标签与属性白名单过滤
内容安全策略响应头示例
内容安全策略响应头示例
# 只允许同源脚本,禁止插件对象与基础路径篡改
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'" always;
# 配合模板引擎默认转义,不要为了省事关掉自动转义上下文与编码读法
| 输出位置 | 编码要求 | 常见错误 |
|---|---|---|
| HTML 正文 | 实体编码尖括号与引号 | 只过滤脚本标签,事件属性仍可注入 |
| 属性值 | 实体编码并始终加引号 | 不加引号导致空格后新属性被拼接 |
| 脚本内部 | 使用序列化输出,避免字符串拼接 | 直接把数据拼进脚本变量 |
| URL 参数 | 做 URL 编码并校验协议 | 只编码空格,未限制协议类型 |
内容安全策略是纵深防御而不是修复手段:编码修复后仍应保留策略,用于降低遗漏点的实际影响。
框架默认转义是最省力的防线,只有在确有富文本需求时才开启原始渲染,并配白名单过滤。