4. 安全测试用例设计:等价类划分、边界值分析、场景法、错误推测法在安全测试中的应用

大家好,我是老张。干安全验证这行十几年了,今天咱们聊聊测试用例设计。

很多人觉得安全测试就是拿工具扫一扫,或者随便想几个攻击场景。说实话,我刚开始也这么干过,结果呢?漏测率惨不忍睹。后来我慢慢悟出一个道理:安全测试,本质上也是测试,经典的黑盒方法一样管用。只不过,咱们的输入域变成了「攻击向量」,预期结果变成了「系统是否被攻破」。

今天我把四种最常用的方法掰开揉碎了讲。你想想看,如果能把等价类、边界值、场景法、错误推测法用好,安全测试的覆盖率至少能提升 50%。

4.1 等价类划分:把无穷的攻击可能性,压缩成有限的测试点

等价类划分,说白了就是「分门别类」。安全测试里,输入空间太大了——SQL 注入有几百种变体,XSS 有几十种编码方式。你不可能全测一遍,对吧?

我的做法是:把「有效」和「无效」的输入分成几大类。每一类里挑一个代表,测过了就算覆盖。

4.1.1 安全测试中的等价类划分原则

我个人习惯把安全输入分成三类:

  • 正常输入类:合法的、符合业务逻辑的数据。比如用户名是字母数字组合,密码长度合规。
  • 异常输入类:不合法的、但不会触发安全漏洞的数据。比如字段超长、类型错误。
  • 恶意输入类:专门用来攻击的 payload。比如 SQL 注入语句、XSS 脚本。

嗯,这里要注意:恶意输入类才是安全测试的重点。但很多人只测这一类,忽略了正常和异常类,结果业务逻辑漏洞全漏了。

4.1.2 实战案例:登录接口的等价类划分

我在项目中遇到过这样一个场景:一个登录接口,用户名和密码都传进去。我划分了以下等价类:

输入域 等价类 示例 预期结果
用户名 正常类 admin 登录成功
用户名 异常类 空字符串 提示「用户名不能为空」
用户名 恶意类 ' OR 1=1 -- 拒绝访问或报错
密码 正常类 P@ssw0rd 登录成功
密码 恶意类 <script>alert(1)</script> HTML 被转义,不执行
我的小技巧: 每个等价类至少选 2-3 个代表值。比如恶意类,SQL 注入选一个,XSS 选一个,命令注入选一个。这样覆盖面更广。

4.2 边界值分析:漏洞往往藏在「临界点」上

边界值分析,说白了就是「找极限」。安全测试里,边界值特别容易出问题。为什么?因为开发人员写代码时,对边界条件的处理往往最薄弱。

我记得有一次测一个文件上传功能。文件大小限制是 10MB。我测了 9.9MB、10MB、10.1MB。结果呢?10MB 的文件上传成功了,但服务器返回了 500 错误,因为内存分配刚好卡在边界上。这就是典型的边界值漏洞。

4.2.1 安全测试中的常见边界

  • 长度边界:输入字段的最小长度、最大长度。比如密码最少 6 位,最多 20 位。测 5、6、7、19、20、21 位。
  • 数值边界:整数的最小值、最大值、0、负数。比如年龄字段,测 -1、0、1、127、128。
  • 时间边界:时间戳的 0、当前时间、未来时间、过去时间。比如 token 过期时间,测刚刚过期和即将过期。
  • 状态边界:状态的切换点。比如订单状态从「待支付」到「已支付」,测中间状态。
避坑指南: 我曾经测过一个支付接口,只测了正常金额和超大金额,忽略了「0 元」这个边界。结果线上有人用 0 元买走了商品……从那以后,我每次都会把「0」和「负数」作为必测边界。

4.3 场景法:从用户故事里挖出安全漏洞

场景法,说白了就是「模拟真实操作」。安全测试不能只盯着单个接口,得看整个业务流程。你想想看,攻击者不会只点一个按钮,他们会走完整个流程,在某个环节搞破坏。

我习惯用「基本流」和「备选流」来设计场景:

  • 基本流:用户正常完成操作的路径。比如注册→登录→下单→支付→收货。
  • 备选流:用户操作出错或异常的路径。比如注册时密码强度不够、支付时余额不足。
  • 恶意流:攻击者故意破坏的路径。比如越权访问他人订单、篡改支付金额。

4.3.1 实战案例:电商下单流程的场景法设计

我在项目中遇到过这样一个场景:一个电商平台,用户下单后可以修改订单金额。我设计了以下场景:

  1. 基本流:用户正常下单,支付成功,收货完成。
  2. 备选流 1:用户下单后,修改收货地址,再支付。
  3. 备选流 2:用户下单后,取消订单,再重新下单。
  4. 恶意流 1:用户下单后,拦截支付请求,篡改金额为 0 元。
  5. 恶意流 2:用户 A 下单,用户 B 越权查看并修改用户 A 的订单。

结果呢?恶意流 1 真的测出了问题——支付接口没有校验金额是否被篡改。这就是场景法的威力。

4.4 错误推测法:靠经验「猜」出漏洞

错误推测法,说白了就是「猜」。靠的是经验、直觉、以及对常见漏洞模式的熟悉程度。这个方法听起来不严谨,但实际非常有效。

我刚开始做安全测试时,总是漏掉一些「奇怪」的漏洞。后来我总结了一个规律:凡是开发人员觉得「不可能发生」的情况,往往就是漏洞所在

4.4.1 常见的错误推测方向

  • 空值:所有输入字段都传 null 或空字符串。
  • 特殊字符:单引号、双引号、反斜杠、换行符。
  • 超长字符串:比如 10000 个字符的密码。
  • 并发操作:同时发送多个请求,比如抢购时并发下单。
  • 重复操作:同一个请求发送两次,比如重复支付。
  • 逆向操作:先执行后一步,再执行前一步。比如先支付再下单。
我的经验之谈: 错误推测法不是瞎猜。你得先了解系统的业务逻辑、技术栈、以及常见的漏洞模式。比如用了 Java,就多想想反序列化漏洞;用了 Node.js,就多想想原型链污染。

4.5 四种方法的综合运用

你可能会问:这四种方法到底怎么搭配使用?我个人的习惯是:

  1. 先用场景法:画出业务流程图,找出所有可能的操作路径。
  2. 再用等价类划分:对每个输入点,划分正常、异常、恶意三类。
  3. 接着用边界值分析:对每个输入点,找出边界值并测试。
  4. 最后用错误推测法:根据经验,补充一些「奇怪」的测试点。

这样一套组合拳下来,安全测试的覆盖率基本能达到 90% 以上。剩下的 10%,靠的是持续学习和积累。

一个小建议: 每次测试完,把漏测的漏洞记录下来,分析是哪种方法没覆盖到。久而久之,你的错误推测法会越来越准。

4.6 本章知识体系图

下面这张图是我自己画的,把四种方法的核心逻辑串起来了。你一看就明白:

安全测试用例设计方法知识体系 安全测试用例设计 等价类划分 边界值分析 场景法 错误推测法 正常类 异常类 恶意类 长度边界 数值边界 状态边界 基本流 备选流 恶意流 空值 特殊字符 并发操作 组合使用,覆盖率可达 90%+

这张图把四种方法的关系讲得很清楚。你从中心出发,沿着四条线往下走,每个分支都有具体的测试点。我个人建议你把它打印出来贴在工位上,每次设计用例时对照着看,不容易漏。


专注资料整理