02 脚本偷袭:三类跨站脚本XSS


02 脚本偷袭:三类跨站脚本 XSS

跨站脚本 XSS 是把攻击者的 JavaScript 送进别人的浏览器去执行的一类漏洞。按脚本进入方式分成存储型、反射型、DOM 型三类;一旦脚本跑起来,窃取 Cookie、劫持会话、钓鱼都成为可能。防御的核心是把所有输出到页面的内容做上下文感知的编码。

注入家族攻的是数据库和操作系统,XSS 换了个更阴险的目标——它不打服务器,直接打进阅读者的浏览器。上一节我们学会把输入当“代码”防,这一节正是在这个直觉上加一层:不仅输入要当不可信,输出到 HTML 的每段用户数据也要按“可能被执行”对待。

一、为什么脚本能混进行页面

浏览器解析 HTML 时,遇上 <script>、事件属性 onerror、<img src> 一段都会当作指令执行。如果一个页面直接把用户搜索词“原样”回显,例如 您搜索的是: 加用户词,那么用户搜索 <script>alert(1)</script>,前端就把这段当成了真正的脚本标签去执行。服务器端没做输出编码,就成了反射型 XSS 的现场。

二、三类 XSS 的区别

存储型(Stored XSS):恶意脚本先进数据库或文件系统(发帖、评论区、昵称),之后任意人访问含脚本的页面都会被触发。它影响面最大,因为一次注入能殃及所有看这个页面的用户。

反射型(Reflected XSS):恶意脚本随 URL 或表单参数发出,服务器把它“反射”回同一响应里执行。它需要骗用户点击带毒链接,影响通常限本人,但结合钓鱼能放大。

DOM 型(DOM-based XSS):漏洞不在服务器端,而在前端 JavaScript 把 location.hash 或 document.referrer 这类值写进 DOM 时的处理。攻击者改 URL 片段即可触发,服务器日志甚至看不到恶意载荷。

三类 XSS 的区别可以用一张维度对比表一眼看穿:脚本落在哪里、带着谁受害、服务器是否有感知。

02-02-fig01

三、攻击者得到了什么

脚本一旦在受害者浏览器里执行,能力边界几乎等于“用户自己授权给页面的能力”:

  • 窃取含会话信息的 Cookie——如果会话 Cookie 没设 HttpOnly,脚本一行 document.cookie 就能拿到。
  • 以受害者身份发请求,把自己变成会话劫持或 CSRF 的发力点。
  • 篡改页面内容做钓鱼:把支付按钮替换成攻击者收款地址。
  • 读取页面 DOM 里的敏感字段,甚至调用用户已授权的第三方接口。

危害等级取决于受害者身份:客服系统里的 XSS 可能撬开管理员会话,权限越高损失越大。

四、为什么“过滤脚本标签”不够

常见又错误的做法是过滤 <script>、onerror 这类关键词。问题在于编码绕法无穷无尽:<scr<script>ipt>、十六进制实体、反引号、大小写混写、event 属性加花括号……黑名单永远追不上白旗。真正可靠的手段是“默认全部编码,允许白名单,按上下文选择编码函数”。

五、工程实践要点

  • 输出编码是主力:每种上下文用对应编码(HTML 正文、HTML 属性、JavaScript 字符串、URL 各有不同转义),框架自带的自动转义模板要一直开着。
  • CSP 兜底:内容安全策略声明只允许哪些来源加载脚本,即使注入发生也限制脚本能加载的资源(CSP 细节在第六幕专门展开)。
  • HttpOnly 与 Secure:会话 Cookie 加 HttpOnly,禁止 JS 读取;加 Secure 只走 HTTPS,双保险削弱窃取价值。
  • 输入验证辅助:只按业务预期放行类型与字符集,宁可占不到便宜也不放行风险内容。

💡 关键直觉:判断某处会不会 XSS,别问“加没加过滤”,而问“这个变量在什么上下文出现,我有没有按那个上下文编码”。同一变量,放到 HTML 正文、属性、脚本串、URL 四种位置,需要四种不同的编码决策。

六、一次完整的演练

背景:一个把用户提交的搜索词直接拼进页面正文回显的演示站。操作:先搜普通词确认回显位置,再提交放进正文上下文无编码的脚本标签。结果:反射型 XSS 触发警示框;把同样的词放进带自动转义的模板渲染,载荷变成无害的纯文本。解读:前者因缺输出编码把数据当代码,后者因默认编码把代码还原成数据。变式:改用 DOM 写入方式演示 DOM 型,用 # 片段传载荷观察服务器日志里根本没有恶意内容,直观对比三类触发差异。

七、排查一条可疑脚本的三步

真实项目里你更常是“事后发现线上有人投了脚本”,而不是“提前预防”。给一个可上手的排查顺序:第一步,在哪一页、哪种上下文发现,把页面前端模板和出网日志并列,定位是存储型源头(数据库里的脏数据)还是反射点(回显没编码)。第二步,看脚本加密了多少——明文脚本直接读意图,加密混淆的要先解码,通常能还原出偷什么 Cookie、hook 什么事件。第三步,评估所触电商城登录、管理后台等页面,优先排查权限最高的入口有没有放大面。这三步做完,你既处理了当前投毒,也反向找到同一编码缺失在哪些页面重复出现,一并补掉。

八、别再问“这串能不能跑”,改问“在哪被跑”

排查示例如少走弯路,关键在于先锁定一次回显落在哪个上下文。真实排查里,最常见的隐藏坑是数据看着“进了页面”却似乎没坏——问题恰恰藏在进页面之后落在哪一个上下文:同一段用户输入,放进 HTML 正文、放进属性值、放进脚本串,需要的编码完全不同。用开发者工具看真实 DOM,找到回显点所在上下文,再按该上下文选择对应编码,基本一两轮就能确定漏在哪。这也是为什么“校验只加在输入口、却不看输出口”的站点容易反复出事。与其依赖多堆几条过滤,不如养成“先看上下文、再谈编码”的习惯——这恰好把三类 XSS 各自落地在哪一层的判断串起来,排查分类时才真正用得上。

本节要点回顾

  • XSS 是把脚本送进他人浏览器执行,按进入方式分存储、反射、DOM 三类。
  • 存储型影响面最大,反射型靠钓鱼骗点击,DOM 型服务器无感知。
  • 脚本能力边界约等于页面被授权的能力,权限越高危害越大。
  • 黑名单过滤挡不住编码绕法,输出编码与 CSP 才是可靠防线。
  • HttpOnly 与 Secure 显著削弱会话窃取价值,是低成本高收益的配套。
作者与出处
原作者:灏天文库
来源:平台策划编纂
整理人: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U