Security 如何使用测试驱动开发确保安全编码?

Security 如何使用测试驱动开发确保安全编码?,security,unit-testing,testing,tdd,fuzzing,Security,Unit Testing,Testing,Tdd,Fuzzing,我一直在关注测试驱动开发(TDD)这一最新趋势。我做的大部分开发都是C或C++。我感到,常见的TDD实践和常见的安全编码实践之间存在着非常明显的冲突。从本质上讲,TDD告诉您不应该为测试没有失败的东西编写新代码。对我来说,这意味着我不应该编写安全代码,除非我有单元测试来检查我的代码是否安全 这带来了两个问题: 如何有效地编写单元测试来测试缓冲区溢出、堆栈溢出、堆溢出、数组索引错误、格式字符串错误、ANSI与Unicode与MBCS字符串大小不匹配、安全字符串处理(来自Howard和LeBlanc

我一直在关注测试驱动开发(TDD)这一最新趋势。我做的大部分开发都是C或C++。我感到,常见的TDD实践和常见的安全编码实践之间存在着非常明显的冲突。从本质上讲,TDD告诉您不应该为测试没有失败的东西编写新代码。对我来说,这意味着我不应该编写安全代码,除非我有单元测试来检查我的代码是否安全

这带来了两个问题:

  • 如何有效地编写单元测试来测试缓冲区溢出、堆栈溢出、堆溢出、数组索引错误、格式字符串错误、ANSI与Unicode与MBCS字符串大小不匹配、安全字符串处理(来自Howard和LeBlanc的“编写安全代码”)

  • 在标准TDD实践的哪一点上应该包括这些测试,因为大部分安全性都是非功能性的

  • 令人惊讶的是,我发现很少有研究讨论TDD和安全性。我遇到的大多数是TDD文件,它们在非常高的级别上提到TDD将“使您的代码更加安全”

    我正在寻找上述问题的任何直接答案,任何与此相关的研究(我已经看过了,没有发现太多),或者TDD大师居住的任何地方,这样我就可以去敲他们的门(虚拟的),看看他们是否有好的答案

    谢谢

    编辑:

    模糊化的主题已经出现了,我认为这是解决这个问题的一个很好的方法。这就提出了一个问题:模糊是否适合TDD?在TDD过程中,模糊适合哪里

    参数化单元测试(可能是自动化的)也出现在我的脑海中。这可能是一种在测试过程中尽早获得模糊结果的方法。我也不确定这在TDD中的确切位置

    编辑2:

    谢谢大家迄今为止的回答。此时,我对如何利用参数化测试作为函数的伪模糊器非常感兴趣。但是,我们如何确定要编写哪些测试来测试安全性呢?我们如何确保我们能充分覆盖攻击空间


    软件安全中的一个众所周知的问题是,如果针对5种攻击场景进行保护,攻击者只会寻找并使用第6种攻击。这是一场很难的猫捉老鼠的游戏。TDD对我们有什么好处吗?

    我先回答你的第二个问题。是的,TDD工程可用于非功能性要求。事实上,通常是这样使用的。改进的模块化设计最常见的好处是无功能性的,但每个实践TDD的人都能看到。我使用TDD验证的其他示例:跨平台、跨数据库和性能

    对于所有测试,您可能需要重新构造代码以使其可测试。这是TDD最大的影响之一——它确实改变了代码的结构。起初,这似乎扰乱了设计,但您很快就会意识到可测试设计更好。无论如何

    字符串解释错误(Unicode与ANSI)特别适合用TDD测试。列举好的输入和坏的输入,并断言它们的解释,通常是很简单的。您可能会发现,您需要稍微重新构造代码,以“使其可测试”;这里我指的是分离特定于字符串的代码的提取方法

    对于缓冲区溢出,如果给定的数据太多,确保例程正确响应也是非常容易测试的。只需编写一个测试并向他们发送太多数据。断言他们做了你所期望的。但是一些缓冲区溢出和堆栈溢出有点棘手。您需要能够使这些事件发生,但您还需要找出如何检测它们是否发生。这可能很简单,比如分配一个包含额外字节的缓冲区,并验证这些字节在测试期间不会改变。。。也可能是其他一些创造性的技巧

    不过,我不确定有没有一个简单的答案。测试需要创造力、纪律性和承诺,但通常是值得的

    • 隔离需要测试的行为
    • 确保您能够检测到问题
    • 知道您希望在错误情况下发生什么
    • 写下测试,看看它是否失败

    希望这有助于

    TDD是构建安全系统的最佳方式。微软开发的所有软件都是模糊的,这可以说是漏洞大幅减少的首要原因。为此,我强烈建议使用。我个人使用Peach成功地找到了缓冲区溢出

    Peach pit文件提供了一种描述应用程序使用的数据的方法。您可以选择要测试的接口。您的应用程序是否读取文件?它有一个开放的端口吗?在您告诉peach输入是什么样子以及如何与应用程序通信之后,您可以将其释放,我知道所有令人讨厌的输入会让您的应用程序浑身呕吐


    为了让一切正常运行,peach有一个很棒的
    测试工具,如果应用程序崩溃,peach会知道,因为它附带了一个调试器。当应用程序崩溃时,peach将重新启动并继续测试。Peach可以对所有崩溃进行分类,并将核心转储与用于崩溃应用程序的输入进行匹配

    参数化测试

    虽然在我的工作中我们没有做缓冲区溢出测试,但我们有模板测试的概念。这些测试是参数化的,需要我们要测试的案例的特定数据。然后,我们使用元编程通过将每种情况的参数应用到模板来动态创建真实的测试。这具有确定性的优点,并且作为自动化测试套件的一部分运行

    我的TDD实践