是否需要成为一名优秀的程序员才能执行安全的源代码分析?

信息安全 源代码 静态分析
2021-08-22 08:12:48

一个人对整体安全风险有很好的了解,知道 OWASP Top 10 漏洞是什么,并且拥有 CEH、CISSP、OSCP 等更多的黑盒测试认证。他还阅读了 OWASP 测试指南、代码审查指南等和备忘单。他是否能够在不了解多种编程语言并精通它们的情况下执行安全的代码审查?

4个回答

这取决于“安全源代码分析”的含义。一个人可以为所欲为。我认为问题在于,当其他人要求进行一种称为“安全源代码分析”的事情时,人们会想知道为什么有人没有资格进行这项工作。

在许多情况下,此类分析必须由主题专家 (SME) 完成。在最终产品中,SME 将发表一个声明,基本上说“我声明此代码是安全的”,其理解比“我查找了一堆已知模式,没有发现任何问题”更深刻的声明。

如果你对一本中国哲学的正版翻译感兴趣,你会相信一个对哲学非常了解,有一堆小抄帮助破译它,但实际上不懂中文的人吗?

想到的一个很好的例子是攻击 SQL 引擎的错误。请原谅我不知道哪个引擎的名称或哪个版本以便您验证,从那以后我一直找不到它。然而,这个错误是尖锐的。错误出现在如下代码中:

int storeDataInCircularBuffer(Buffer* dest, const char* src, size_t length)
{
    if (dest->putPtr + length < dest->putPtr)
        return ERROR; // prevent buffer overflow caused by overflow
    if (dest->putPtr + length > dest->endPtr) {
        ... // write the data in two parts
        return OK;
    } else {
        ... // write the data in one part
        return OK;
    }
}

此代码旨在成为循环缓冲区的一部分。在循环缓冲区中,当您到达缓冲区的末尾时,您会绕回。有时这会迫使您将传入的消息分成两部分,这没关系。然而,在这个 SQL 程序中,他们关心的情况length可能大到足以导致dest->putPtr + length溢出,从而为缓冲区溢出创造机会,因为下一次检查将无法正常工作。所以他们进行了测试:if (dest->putPtr + length < dest->putPtr). 他们的逻辑是,如果发生溢出,则该语句可能为真的唯一方法是,因此我们捕获溢出。

这造成了一个实际上被利用的安全漏洞,必须修补。为什么?好吧,原作者不知道的是,C++ 规范声明指针溢出是未定义的行为,这意味着编译器可以做它想做的任何事情。碰巧的是,当原作者测试它时,gcc实际上发出了正确的代码。然而,在后来的几个版本中,gcc 确实进行了优化以利用这一点。它看到没有定义的行为if可以让该语句通过其测试,并对其进行优化!

因此,对于一些版本,人们拥有具有漏洞利用的 SQL 服务器,即使代码具有显式检查以防止所述漏洞利用!

从根本上说,编程语言是非常强大的工具,可以轻松地咬住开发人员。分析这是否会发生确实需要相关语言的坚实基础。

(编辑:Greg Bacon 非常棒,足以挖掘出一个 CERT 警告:漏洞说明 VU#162289 C 编译器可能会默默地丢弃一些环绕检查。还有这个相关的。谢谢 Greg!)

我认为你需要成为一名优秀的程序员才能成功,所以我建议你成为一名优秀的程序员。您的工具包/扫描仪可能遗漏了很多东西。老实说,我不建议完全依赖工具为您扫描代码,因为漏洞不断变化,并且有人可能以扫描程序无法检测到漏洞的方式进行编码。

单步调试代码并了解它如何工作以及它不应该如何工作的能力是确保软件开发安全的基础。让开发人员意识到安全问题正是您在生产可靠产品时所需要的,也是您在代码审查期间所需要的。

虽然是的,但您可以使用扫描仪和工具包点击并检查漏洞,但这在宏伟的计划中不会非常有效。如果您可以自己查看代码并确定它是好是坏,您知道您的效率会提高多少吗?哇更好。

如果您不知道自己在做什么,请不要尝试通过安全的代码审查,但如果您觉得自己无法进行良好的审查,请不要完全放弃这个想法。我建议尝试通过创建自己的安全代码审查模型来学习,并通过几次以确保一切正常。

但是,您绝对应该不仅要学习编码,而且要学好编码。

安全专家是否能有效地执行源代码分析而不是熟练的程序员是值得怀疑的。许多漏洞是技术或语法编码实践的结果,这些实践以某种轻微的方式被滥用。缺少分号、等号而不是双等号、数组边界在第一天被双重定义但一个版本在后续版本中更改、缺少括号、内存泄漏,所有这些都导致了漏洞。有经验的开发人员可能会看到这些,但新手可能不会。

您的安全专家应该做的是鼓励工程师使用自动扫描工具,例如静态代码分析器、模糊测试器和动态应用程序验证器。帮助工程团队了解输入验证、注入攻击、信任边界。树立安全缺陷需要适当优先排序并迅速解决的意识。安排并进行渗透测试。最重要的是,让工程师对彼此的工作进行代码审查。

是的,安全专家应该能够读懂代码,但这并不意味着他有资格成为代码安全的仲裁者。

这取决于您的期望。如果测试人员对安全概念有深入的了解,即使他只能遵循代码流而没有对特定的编程语言有更深入的了解。

\0但是,如果测试人员对语言没有更深入的了解,则不会发现特定于语言的安全问题,例如缓冲区溢出、非一错误、unicode 的处理或由数据类型的大小和有符号与无符号等引起的问题,不良做法和特定于语言的典型不安全模式。以 Java 漏洞的历史为例,即使是 Java 专家开发人员也没有注意到他们通过向语言添加反射而在语言沙箱中打出的漏洞,只有对语言内部有深入了解的外部专家才能检测到漏洞。