Security 如何使用测试驱动开发确保安全编码?
我一直在关注测试驱动开发(TDD)这一最新趋势。我做的大部分开发都是C或C++。我感到,常见的TDD实践和常见的安全编码实践之间存在着非常明显的冲突。从本质上讲,TDD告诉您不应该为测试没有失败的东西编写新代码。对我来说,这意味着我不应该编写安全代码,除非我有单元测试来检查我的代码是否安全 这带来了两个问题:Security 如何使用测试驱动开发确保安全编码?,security,unit-testing,testing,tdd,fuzzing,Security,Unit Testing,Testing,Tdd,Fuzzing,我一直在关注测试驱动开发(TDD)这一最新趋势。我做的大部分开发都是C或C++。我感到,常见的TDD实践和常见的安全编码实践之间存在着非常明显的冲突。从本质上讲,TDD告诉您不应该为测试没有失败的东西编写新代码。对我来说,这意味着我不应该编写安全代码,除非我有单元测试来检查我的代码是否安全 这带来了两个问题: 如何有效地编写单元测试来测试缓冲区溢出、堆栈溢出、堆溢出、数组索引错误、格式字符串错误、ANSI与Unicode与MBCS字符串大小不匹配、安全字符串处理(来自Howard和LeBlanc
软件安全中的一个众所周知的问题是,如果针对5种攻击场景进行保护,攻击者只会寻找并使用第6种攻击。这是一场很难的猫捉老鼠的游戏。TDD对我们有什么好处吗?我先回答你的第二个问题。是的,TDD工程可用于非功能性要求。事实上,通常是这样使用的。改进的模块化设计最常见的好处是无功能性的,但每个实践TDD的人都能看到。我使用TDD验证的其他示例:跨平台、跨数据库和性能 对于所有测试,您可能需要重新构造代码以使其可测试。这是TDD最大的影响之一——它确实改变了代码的结构。起初,这似乎扰乱了设计,但您很快就会意识到可测试设计更好。无论如何 字符串解释错误(Unicode与ANSI)特别适合用TDD测试。列举好的输入和坏的输入,并断言它们的解释,通常是很简单的。您可能会发现,您需要稍微重新构造代码,以“使其可测试”;这里我指的是分离特定于字符串的代码的提取方法 对于缓冲区溢出,如果给定的数据太多,确保例程正确响应也是非常容易测试的。只需编写一个测试并向他们发送太多数据。断言他们做了你所期望的。但是一些缓冲区溢出和堆栈溢出有点棘手。您需要能够使这些事件发生,但您还需要找出如何检测它们是否发生。这可能很简单,比如分配一个包含额外字节的缓冲区,并验证这些字节在测试期间不会改变。。。也可能是其他一些创造性的技巧 不过,我不确定有没有一个简单的答案。测试需要创造力、纪律性和承诺,但通常是值得的
- 隔离需要测试的行为
- 确保您能够检测到问题
- 知道您希望在错误情况下发生什么
- 写下测试,看看它是否失败
希望这有助于TDD是构建安全系统的最佳方式。微软开发的所有软件都是模糊的,这可以说是漏洞大幅减少的首要原因。为此,我强烈建议使用。我个人使用Peach成功地找到了缓冲区溢出 Peach pit文件提供了一种描述应用程序使用的数据的方法。您可以选择要测试的接口。您的应用程序是否读取文件?它有一个开放的端口吗?在您告诉peach输入是什么样子以及如何与应用程序通信之后,您可以将其释放,我知道所有令人讨厌的输入会让您的应用程序浑身呕吐
为了让一切正常运行,peach有一个很棒的
测试工具,如果应用程序崩溃,peach会知道,因为它附带了一个调试器。当应用程序崩溃时,peach将重新启动并继续测试。Peach可以对所有崩溃进行分类,并将核心转储与用于崩溃应用程序的输入进行匹配 参数化测试
虽然在我的工作中我们没有做缓冲区溢出测试,但我们有模板测试的概念。这些测试是参数化的,需要我们要测试的案例的特定数据。然后,我们使用元编程通过将每种情况的参数应用到模板来动态创建真实的测试。这具有确定性的优点,并且作为自动化测试套件的一部分运行
我的TDD实践