软件安全的大风险是检验工具及过程不透明的本质,以及不同的检验技术(例如自动化动态测试)不能覆盖假阴性错误的潜在可能性。
  尽管安全软件开发生命周期(SDLC)有很多相关的佳实践,但大多数组织依然有一种倾向,那是主要依赖测试去构建安全的软件。当前的测试方法有一个严重的副作用,即组织不太清楚哪些已经被其解决方案测试过,而(甚至更重要的是)还有哪些未被测试过。我们的研究表明,任何单一的自动化保证机制多可以检验44%的安全需求。NIST 静态分析工具博览会发现,Tomcat中有26个已知的漏洞,但所有静态分析工具综合起来只报告了其中4个警告。因为依赖不透明的检验过程是一种普遍存在的习惯,甚至已经成为行业标准,因此许多组织在构建安全的软件时,满足于把测试作为主要的手段。
  举个例子,假设你雇用一家咨询公司为你的软件执行渗透测试。许多人将这种测试称为“黑盒”(基于同名的质保技术),测试人员没有详细的系统内部构件知识(比如系统代码)。执行测试之后,一成不变地生成一份报告,概括你应用中的几类漏洞。你修复了漏洞,然后提交应用做回归测试,下一份报告反馈说“已清除”——也是说没有任何漏洞了。或者充其量仅仅告知你,你的应用在同一时间范围内不会被同样的测试人员以同样的方式攻破。但另一方面,它不会告诉你:
  你的应用中还有哪些潜在的威胁?
  你的应用中哪些威胁“其实不易受到攻击”?
  你的应用中有哪些威胁未被测试人员评估?从运行期的角度来看,哪些威胁无法测试?
  测试的时间及其他约束如何影响了结果的可靠性?例如,如果测试人员还有5天时间,他们还将执行哪些其他的安全测试?
  测试人员的技能水平有多高?你能否从不同的测试人员或者另一家咨询公司手中取得一组相同的结果?
  以我们的经验来看,组织无法回答以上大多数问题。黑盒是两面的:一方面,测试人员不清楚应用的内部结构;而另一方面,申请测试的组织对自己软件的安全状况也缺乏了解。并不只是我们意识到了这个问题:Haroon Meer在44con上讨论了渗透测试的挑战。这些问题大多数都适用于任何形式的验证:自动化动态测试、自动化静态测试、手工渗透测试以及手工代码审查。实际上, 近期有一篇论文介绍了源代码审查中类似的挑战。
  关于需求的实例
  为了更好地说明这个问题,让我们看一些常见的高风险软件的安全需求,以及如何将常见的验证方法应用到这些需求上。
  需求:使用安全的哈希算法(如SHA-2)和的混淆值(salt value)去哈希(Hash)用户密码。多次迭代该算法。
  在过去的一年里,LinkedIn、Last FM和Twitter发生了众所周知的密码泄露事件,对于此类缺陷,本条需求是具体地、合乎时宜的。
  如何应用常见的验证方法:
  自动化运行期测试:不可能访问已存的密码,因此无法使用此方法验证本需求
  手工运行期测试:只有另一些开发导致已存密码转储时,才能使用此方法验证本需求。这并不是你所能控制的,因此你不能依靠运行期测试去验证本需求。
  自动化静态分析:只有满足以下条件时,才可以用此方法验证本需求:
  工具清楚身份认证是如何工作的(例如,使用了标准的组件,像Java Realms)
  工具清楚应用程序使用了哪个特定的哈希算法
  如果应用程序为每次哈希使用了的混淆值,工具要清楚混淆算法和混淆值
  实际上,认证有很多实现方法,指望静态分析方法全面地验证本需求是不切实际的。更为实际的方案是,使用工具简单地确认认证程序,并指出必须进行安全的哈希和混淆处理。另一个方案是,你来创建自定义规则,用以鉴定算法和哈希值,确认它们是否符合你专属的策略,尽管,在我们的经验中这种实践极为罕见。
  手工代码审查:对于本需求,这是可靠的常见验证方法。手工评估人员能够理解哪一段代码中发生了认证,验证哈希和混淆处理符合佳实践。
  需求:在SQL语句中绑定变量以预防SQL注入
  SQL 注入是具破坏性的应用漏洞之一。近期发现在Ruby on Rails中有一个缺陷,在其技术栈上搭建的应用系统会受到SQL注入攻击。
  如何应用常见的验证方法
  自动化运行期测试:虽然,运行期测试通过行为分析也许能够发现存在的SQL注入,但是,却不能证明没有SQL注入。因此,自动化运行期测试不能充分地验证本需求
  手工运行期测试:与自动化运行期测试一样具有相同的局限性
  自动化静态分析:通常能够验证本需求,特别是当你使用标准类库访问SQL数据库时。你是否将用户输入动态地拼接为SQL语句,还是使用正确地变量绑定,工具应该都可以分辨得出来。然而,这是有风险的,在以下场景中静态分析可能会漏掉SQL注入漏洞:
  你在数据库上使用存储过程,并且无法扫描数据库代码。在某些情况下,存储过程也易受到SQL注入
  你使用了一种对象关系映射(ORM)类库,但你的静态分析工具不支持这种类库。对象关系映射也易受到注入。
  你使用非标准的驱动或类库去连接数据库,并且驱动没有正确地实现常见地安全控制(比如预编译语句)
  手工代码审查:与静态分析一样,手工代码审查能够确认没有SQL注入漏洞。然而,实际上产品应用中可能有几百或成千上万条SQL语句。手工审查每一条语句不仅非常耗时,而且容易出错。
  需求:使用授权检查以确保用户无法查看其他用户的数据。
  我们每年都能听到此类 漏洞新的事例。