模糊测试是什么
模糊测试(Fuzzing)向程序输入大量随机或变异数据,监测崩溃、断言失败与超时:适合解析器、协议实现与安全敏感组件。覆盖驱动的模糊测试以代码覆盖为引导,能更快钻进深层路径;产出的崩溃样本应归档为回归用例,形成长期防护。
基本信息
| 常见工具 | AFL++、libFuzzer、OSS-Fuzz、go fuzz、Jazzer(Java) |
|---|---|
| 关注信号 | 崩溃、挂起、内存错误、未处理异常 |
| 输入来源 | 种子语料加变异,或按格式规范生成 |
| 运行方式 | 本地、CI 定时任务或托管平台 |
| 产出物 | 崩溃样本、复现命令、最小化输入 |
| 适用对象 | 解析器、编解码、协议实现、安全敏感组件 |
| 覆盖引导 | 以插桩反馈引导变异,效率高于纯随机 |
Go fuzz 示例
Go fuzz 示例
func FuzzParse(f *testing.F) {
f.Add("1+2") # 种子语料
f.Fuzz(func(t *testing.T, expr string) {
_ = Parse(expr) # 不 panic 即通过
})
}典型使用场景
- 解析器加固:对格式解析入口持续模糊,暴露边界崩溃。
- 协议实现:用报文变异测试长度字段与状态机处理。
- 安全评估:在隔离环境中发现越界类内存问题。
- CI 定时运行:夜间跑固定时长,持续积累崩溃样本。
- 回归扩展:把历史崩溃样本固化进模糊语料库。
- 健壮对比:比较不同实现对畸形输入的容错表现。
- 差分测试:同一输入喂两个实现,比对输出差异定位问题。
- 文本处理入口:对配置解析、模板与正则处理做模糊。
运行要点
| 要点 | 做法 |
|---|---|
| 隔离 | 容器或专用机器运行,失败不影响他人 |
| 限额 | 限制 CPU、内存与磁盘,防止占满机器 |
| 时长 | CI 定时任务设固定时长,持续与一次兼顾 |
| 样本 | 崩溃样本最小化后归档进语料库 |
崩溃样本要归档为回归用例;修复前先确认输入不含敏感数据。
只统计执行次数意义有限:关注覆盖增长与新路径发现效率。
模糊测试放在隔离环境执行:崩溃与资源耗尽可能影响同机其他服务。
挂起与超时同样是信号:资源型缺陷常在长时间运行后暴露。