安全测试-05-文件上传、XSS 与 CSRF 这些高频漏洞怎么测

安全测试里有一类问题很典型:

  • 这些问题本身都不陌生
  • 资料也很多
  • 但一到真实项目里,还是会反复出现

最典型的就是这三类:

  • 文件上传
  • XSS
  • CSRF

它们之所以值得长期固定检查,不是因为概念经典,而是因为它们非常贴近日常业务功能:

  • 头像上传
  • 附件上传
  • 富文本内容
  • 搜索框、备注、评论
  • 后台配置页面
  • 审批、删除、修改资料这类表单动作

这篇文章不打算讲漏洞定义百科,而是讲更实用的问题:

在真实业务测试里,这三类问题到底怎么测,怎么判断问题是否真的成立。

一、先说结论:这三类问题最怕“只测表面”

这三类问题在现场都很容易被测偏。

常见误区是:

  • 文件上传只看前端后缀限制
  • XSS 只在输入框里随手塞个 alert(1)
  • CSRF 只看有没有 token 字段

这些都不够。

真正要确认的是:

  • 文件最终有没有按危险方式被保存和暴露
  • 恶意脚本最终有没有进入真实渲染上下文并执行
  • 关键动作最终能不能在用户不知情的情况下被跨站触发

所以这三类问题都不能只停留在“请求能发出去”,而要看到最终影响。

二、文件上传最值得优先看的,不是“能传文件”,而是“系统最终怎么处理文件”

文件上传问题最容易被低估,因为功能视角往往只看:

  • 能不能上传成功
  • 页面能不能看到附件

安全视角还要继续往下问:

  • 服务端按什么规则识别文件类型
  • 文件名、扩展名、路径有没有被可信处理
  • 上传后的文件最终放到哪里
  • 访问下载时是按静态资源直接暴露,还是经过安全处理

1. 最值得优先测的几个点

  • 只校验前端后缀,后端不校验
  • 只看 Content-Type,不看实际文件内容
  • 文件名可控,路径拼接不严谨
  • 上传目录可直接访问
  • 富文本或附件允许上传带脚本的可执行内容

2. 一套最小执行骨架

通常至少会做这几组动作:

  1. 改后缀
  2. Content-Type
  3. 改文件名
  4. 上传包含脚本或危险内容的文件
  5. 上传成功后直接访问文件 URL

例如会重点试这些组合:

  • test.jpg.php
  • shell.jsp.png
  • SVG 中带脚本
  • HTML 文件伪装成图片

3. 重点不只是看“传进去了”,还要看“后面怎么被访问”

这一步很关键。

有些系统虽然把危险文件传进去了,但最终:

  • 下载时强制附件方式返回
  • 不在公网目录暴露
  • 做了文件重命名和隔离

这时风险和“直接可执行、可访问”完全不是一个量级。

所以文件上传测试最终要回答的是:

  • 能不能绕过校验
  • 绕过之后能不能形成实际可利用路径

三、XSS 最怕只测输入,不看最终渲染上下文

对 XSS 的测试停留在:

  • 输入 <script>alert(1)</script>
  • 页面没弹框
  • 于是判断没问题

这太粗了。

真正要看的问题是:

  • 输入内容最终落到了哪里
  • 是进入 HTML、属性、脚本还是 URL 上下文
  • 页面渲染前有没有正确转义
  • 富文本场景有没有做白名单过滤

1. 哪些位置最值得优先看

通常优先看这些地方:

  • 评论、备注、简介、公告
  • 富文本编辑器
  • 搜索框回显
  • 用户昵称、头像说明、工单内容
  • 后台运营配置项
  • 报表标题、导出名称、消息模板

因为这些位置经常满足两个条件:

  • 输入来源是用户可控的
  • 输出位置是其它用户会看到的

2. 一套更实用的测试顺序

第一步:先确认输入能否原样保存

例如输入:

1
<img src=x onerror=alert(1)>

先看保存后再打开详情页、列表页、管理页时,这段内容是否被原样带出来。

第二步:再确认它落在什么上下文

同样一段内容,落在不同上下文风险完全不同:

  • 普通文本节点
  • HTML 属性
  • JavaScript 字符串
  • URL 参数

这一步决定了后面 payload 应该怎么调整。

第三步:最后再判断是否真的执行

不要只在输入瞬间看结果。

要同时看:

  • 详情页
  • 列表页
  • 审核页
  • 后台管理页
  • 导出预览页

很多 XSS 不是在用户自己提交时触发,而是在别人查看、审核、管理时触发。

四、CSRF 最怕只看 token 字段,不看关键动作是否真的可跨站触发

CSRF 在 里会被简单理解成:

  • 看请求里有没有 _csrf
  • 如果有,就算安全

这不严谨。

真正要问的是:

  • 关键动作是不是完全依赖浏览器自动带上的身份
  • 有没有额外防护机制
  • 恶意页面能不能诱导浏览器替用户发出有效请求

1. 哪些动作最值得优先看

我优先看这些动作:

  • 修改邮箱、手机号、密码
  • 新增管理员、调整角色
  • 审批通过、删除、封禁
  • 收货地址修改、提现申请、退款确认

因为这些动作一旦被跨站触发,业务后果通常很直接。

2. 一套最小执行骨架

CSRF 的最小测试,通常可以按这几步来:

  1. 先确认目标动作是否依赖 Cookie 或浏览器自动身份
  2. 再看请求是否要求额外 token、验证码、二次确认
  3. 构造一个简单表单或请求页面
  4. 在受害者已登录状态下访问这个页面
  5. 看关键动作是否真实生效

如果动作真实生效,问题才算真正成立。

3. 重点不要只看“请求能发”,要看“动作是否落地”

有些接口跨站请求能发出去,但:

  • 被 SameSite 拦住了
  • 被 token 校验挡住了
  • 被二次确认挡住了

这时风险要按真实结果判断,而不是按“理论能发请求”判断。

五、一套适合业务测试的统一检查表

如果要把这三类问题沉淀成稳定动作,建议至少固定下面这张检查表。

类型 优先场景 首测动作 关键确认点
文件上传 头像、附件、富文本、后台上传 改后缀、改类型、改文件名 是否可访问、可执行、可传播
XSS 评论、备注、富文本、后台配置 提交带脚本内容 是否进入渲染上下文并执行
CSRF 修改、审批、删除、授权 构造跨站请求 用户已登录情况下动作是否真实落地

这张表的价值是让测试不要只停留在“看到一个输入框就试一下”,而是先把高风险位置和验证目标对齐。

六、最容易踩的几个坑

1. 文件上传只看前端限制

前端限制通常价值很有限。
真正要看的是后端是否信了这些信息,以及文件最终如何落盘和暴露。

2. XSS 只在单一页面测一次

很多输入在提交页不执行,但会在:

  • 列表页
  • 审核页
  • 管理后台
  • 邮件通知预览

这些地方触发。

3. CSRF 只看有没有 token 字段

有 token 不等于安全。
还要看:

  • token 是否真的校验
  • 是否能被重用
  • 是否只做了表面字段校验

4. 只看技术现象,不看业务影响

例如一个 XSS 只能影响用户自己的草稿页,风险和“能打到管理员审核页”的 XSS 完全不是一个级别。

七、真实案例:为什么一个“备注字段”最后打到了管理员后台

场景

一个工单系统里,提交工单时有个“问题备注”字段。
业务同学觉得这只是普通文本,风险不高。

功能测试时,这个字段表现正常:

  • 能保存
  • 能在工单详情页查看
  • 管理员后台也能看到

执行

我在备注里填入了一段更偏事件型的内容:

1
<img src=x onerror=alert('xss')>

然后我按这几个位置逐个验证:

  1. 提交人自己的详情页
  2. 工单列表页
  3. 管理员后台审核页

现象

结果很有代表性:

  • 提交人详情页里,这段内容被普通文本显示,没有执行
  • 但管理员后台审核页里,备注内容被直接拼进了富文本区域
  • 管理员打开该工单时,脚本真正执行了

也就是说,这不是一个“用户自己看自己页面”的低风险问题,而是一个能打到高权限审核后台的存储型 XSS。

排查

顺着前后端实现看,问题链路很清楚:

  • 提交接口没有过滤危险标签
  • 前台详情页做了 HTML 转义
  • 但后台审核页为了保留格式,直接使用了未转义内容

本质上不是“系统没有任何防护”,而是:

  • 不同页面对同一字段处理不一致
  • 高权限页面恰好走了最危险的渲染方式

修复

最后给研发的修复建议不是简单一句“过滤 script”,而是分层做:

  1. 对富文本和普通文本字段分开处理
  2. 对后台审核页统一做安全渲染或白名单清洗
  3. 建立一组固定 payload 回归用例
  4. 把“普通用户输入 -> 管理员查看”的链路列为长期回归项

这个案例很典型地说明:

XSS 的关键从来不只是“用户能不能输入”,而是“高权限用户最终怎么渲染这段内容”。

八、怎么把这类问题持续沉淀下来

更合适的做法是把这三类检查做成固定的专项清单。

第一层:手工检查清单

每个高风险模块固定检查:

  • 上传文件后最终如何访问
  • 富文本、备注、评论是否在多页面回显
  • 关键表单动作是否依赖浏览器自动身份
  • 高权限页面是否会渲染低权限用户输入

第二层:自动化或半自动化验证

适合沉淀成脚本或固定数据集的包括:

  • 文件上传测试样本集
  • 一组固定 XSS payload
  • 关键修改/审批动作的 CSRF 复现页面

这样后续系统改版、编辑器替换、上传链路调整时,问题不会完全靠人工再发现一遍。

九、写在最后

文件上传、XSS、CSRF 这些问题之所以一直值得测,不是因为老,而是因为它们总是躲在最普通的业务功能里。

真正有效的做法,不是背很多 payload,而是把三个问题都落到真实影响上看:

  • 文件最终怎么存、怎么访问
  • 输入最终在哪里、以什么方式被渲染
  • 动作最终能不能在用户不知情的情况下被跨站触发

只要把这三件事看清楚,很多表面上“看起来没什么”的问题,风险级别就会一下子变得很明确。