首页/安全/漏洞与攻击面速查/XSS 跨站脚本原理与基本防护
Web 漏洞原理与防护55 条

XSS 跨站脚本原理与基本防护

XSS 源于把不可信数据当 HTML/JS 输出到浏览器,脚本会在受害者会话中执行;防护基础是上下文相关的输出编码,配合 Cookie 属性、CSP 与富文本净化形成纵深。

漏洞与攻击面速查安全更新于 2026-10-13

XSS 是什么

XSS(跨站脚本)的成因是把不可信数据当代码输出到了浏览器:攻击者输入的片段被页面当作 HTML 或 JavaScript 执行,脚本于是在受害者的会话里运行。它能读取页面可见数据、代替用户发起操作、盗取未受保护的凭据,配合蠕虫式传播还能一次性影响大量用户。防护的根本手段是输出编码——同一份数据在 HTML 文本、属性、URL、JavaScript 四种上下文里需要不同的编码方式,因此安全边界在渲染层而不是输入层。

基本信息

风险类别OWASP Top 10 2021 A03 注入类;CWE-79
成因用户数据未按输出上下文编码,被当作 HTML/JS 解析
危害会话劫持、伪造操作、钓鱼与页面篡改、蠕虫式扩散
基础防护按上下文做输出编码,默认转义为常态
纵深防护HttpOnly 与 SameSite、CSP、富文本白名单净化
框架差异主流前端框架默认转义插值,风险集中在显式绕过点

典型使用场景

  • 用户昵称、评论、工单标题等回显位置:最常见的存储型注入点
  • 搜索关键词回显:搜索页把关键词原样写回页面,形成反射型
  • URL 参数拼接进页面内联脚本:前端用参数拼 JS 变量时最易出事
  • 富文本编辑器内容与第三方 Markdown 渲染:需要白名单净化而不是全转义
  • 后台运营查看用户提交内容:管理员会话权限高,被利用后影响面更大
  • 移动端内嵌 WebView:可进一步触达本地能力,需要独立评估

四种上下文的编码方式

四种上下文的编码方式
HTML 文本:< 转 &lt;,> 转 &gt;,& 转 &amp;
属性值:引号包裹,编码双引号与单引号,避免未加引号的属性
URL 参数:URL 编码,并对协议做白名单,只允许 http/https
JS 上下文:用 JSON 序列化后嵌入,禁止字符串拼接构造脚本
CSS 与 style 属性:只允许固定枚举值,不接受用户直接输入
# 关键:编码必须发生在最终输出位置,而不是统一在入库前处理

三类 XSS 的差别

类型触发方式主要检测位置
反射型单次请求的数据被回显执行搜索、跳转、错误页的回显参数
存储型恶意内容落库,被其他用户访问时执行留言、昵称、工单、导入的模板
DOM 型浏览器端脚本把不可信数据写入 DOM前端代码里的 innerHTML、eval、location 赋值

CSP 与 Cookie 加固

CSP 与 Cookie 加固
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-<每请求随机值>'; object-src 'none'
# CSP 是兜底:即使存在注入点,也能阻止内联脚本执行
Set-Cookie: sid=<值>; HttpOnly; Secure; SameSite=Lax
# HttpOnly 阻断脚本读取 Cookie,SameSite 降低跨站请求被自动携带的风险
# 两者都不能替代输出编码,只是把单点问题的影响范围压小
开 CSP 时先跑报告模式(Content-Security-Policy-Report-Only)收集违规来源,再切强制模式,避免直接上线拦断业务脚本。
只做输入过滤很难覆盖全部场景:同一份数据可能出现在多个输出位置,同一位置的编码规则还随浏览器与上下文变化,所以以输出编码为主、输入校验为辅。

验证与巡检要点

  • 用无害标记字符验证回显位置:先看数据落在 HTML、属性还是脚本里,再判定该位置需要的编码
  • 覆盖多出口:同一个字段常同时出现在页面、JSON 接口、导出文件与邮件模板中
  • 检查前端拼接点:搜索 innerHTML、document.write、eval 与模板字符串拼接等写法
  • 验证净化库配置:导出富文本白名单,确认不含事件属性与危险协议
  • 回归正常展示:编码改造后确认中文、表情、特殊符号显示正常,避免修一处坏一处
JSON 接口也有上下文问题:如果前端把接口返回值直接插入 DOM,接口层就算做了转义也可能在浏览器里被还原后执行,安全边界要看数据最终落在哪里。

易错点

  • 只做输入过滤不做输出编码:不同上下文编码规则不同,输入层无法覆盖所有输出位置
  • 用黑名单过滤 script 标签:大小写变形、事件属性、编码拆分都能绕过,必须依赖输出编码
  • 同一份数据在多个位置直接拼接:JSON 接口、日志回显、邮件模板各有一套转义规则,遗漏任一处都算未修复
  • 给富文本开全量放行:净化库白名单过宽时仍可注入事件属性,应只允许必要标签与属性并禁用内联事件
  • 把 HttpOnly 当成修复手段:它只挡住 Cookie 读取,请求伪造与页面篡改照旧可以发生

数据来源与参考

  • OWASP XSS Prevention Cheat Sheet
  • OWASP Top 10 A03 注入
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌