模糊测试

模糊测试 （fuzz testing, fuzzing）是一种软件测试技术。其核心思想是将自动或半自动生成的随机数据输入到一个程序中，并监视程序异常，如崩溃，断言（assertion）失败，以发现可能的程序错误，比如内存泄漏。模糊测试常常用于检测软件或计算机系统的安全漏洞。
模糊测试最早由威斯康星大学的Barton Miller于1988年提出。他们的工作不仅使用随机无结构的测试数据，还系统的利用了一系列的工具去分析不同平台上的各种软件，并对测试发现的错误进行了系统的分析。此外，他们还公开了源代码，测试流程以及原始结果数据。
模糊测试工具主要分为两类，变异测试（mutation-based）以及生成测试（generation-based）。模糊测试可以被用作白盒，灰盒或黑盒测试。文件格式与网络协议是最常见的测试目标，但任何程序输入都可以作为测试对象。常见的输入有环境变量，鼠标和键盘事件以及API调用序列。甚至一些通常不被考虑成输入的对象也可以被测试，比如数据库中的数据或共享内存。
对于安全相关的测试，那些跨越可信边界的数据是最有趣的。比如，模糊测试那些处理任意用户上传的文件的代码比测试解析服务器配置文件的代码更重要。因为服务器配置文件往往只能被有一定权限的用户修改。

历史

模糊测试这个词最早产生于1988年威斯康星大学的Barton Miller教授的一个课程实验。实验内容是开发一个基本的命令行模糊器以测试Unix程序。这个模糊器可以用随机数据来“轰炸”这些测试程序直至其崩溃。类似的实验于1995年被重复，并且包括了图形界面程序（例如X Window System），网络协议和系统API库。一些后续工作可以测试Mac和Windows系统上的命令行程序与图形界面程序。
关于模糊测试更早的想法可以追溯到1983年前。Steve Capps于当时开发了一个叫做The Monkey的Macintosh程序以测试Mac程序，并曾被用于发现MacPaint的程序错误。
另一个早期的模糊测试工具是crashme，于1991年发布。其主要功能是让Unix以及类Unix系统去执行随机机器指令以测试这些系统的健壮性。

用途

模糊测试通常被用于黑盒测试。其回报率通常比较高。当然，模糊测试只是相当于对系统的行为做了一个随机采样，所以在许多情况下通过了模糊测试只是说明软件可以处理异常以避免崩溃，而不能说明该软件的行为完全正确。这表明模糊测试更多是一种对整体质量的保证，并不能替代全面的测试或者形式化方法。作为一种粗略的可靠性度量方法，模糊测试可以提示程序哪些部件需要特殊的注意。对于这些部件可以进一步使用代码审计，静态分析以及代码重写。

技术

模糊测试工具通常可以被分为两类。变异测试通过改变已有的数据样本去生成测试数据。生成测试则通过对程序输入的建模来生成新的测试数据。
最简单的模糊测试是通过命令行，网络包或者事件向一个程序输入一段随机比特流。这种技术当前依然是有效的发现程序错误的方法。另一个常见且易于实现的技术是通过随机反转一些比特或者整体移动一些数据块来变异已有的输入数据。但是，最有效的模糊测试需要能够理解被测试对象的格式或者协议。这可以通过阅读设计规格来实现。基于设计规格的模糊工具包含完整的规格，并通过基于模型的测试生成方法去遍历规格，并在数据内容，结构，消息，序列中引入一些异常。这种“聪明的”模糊测试也被称作健壮性测试，句法测试，语法测试以及错误注入。这种协议感知的特性也可以启发式的从例子中生成。相关的工具有Sequitur。
模糊测试也可以与其他技术结合。白盒模糊测试结合了符号执行技术与约束求解技术。演化模糊测试则利用了一个启发的反馈来有效的实现自动的探索性测试。