是否应该重用或重写安全关键代码?

信息安全 源代码 软件 安全编码
2021-08-29 11:54:57

通常,在编程中,重用代码总是比编写自己的算法实现更好。如果一个实现已经存在很长时间并且仍然被许多项目使用,那么它可能一开始就设计得很好,已经接受了大量的测试和调试,也许最重要的是其他人负责维护这意味着有更多时间专注于您正在构建的特定软件产品。

但是,我想知道这个原则是否仍然适用于安全关键代码,这些代码执行加密和身份验证等任务,或者出于任何原因以高权限运行。如果一个算法的一个实现被许多软件系统共享,那么人们就会有很强的动力去破解它,当发现其中的缺陷时,很可能是一场巨大的安全灾难。Heartbleed 和 Shellshock 是我最近想到的两个例子。对于封闭源代码示例,请从 Adob​​e 中选择任何内容 :)

许多不同的软件共享一个安全关键库也使该库成为想要在其中插入后门的攻击者的首选目标。在一个有大量活动的大型开源项目中,不太可能注意到一个后门提交,它还具有大量其他更正(例如代码样式清理)作为诱饵。

考虑到所有这些,代码重用是否仍然被认为是代码执行安全关键任务的好习惯?如果是这样,应该采取哪些预防措施来减轻该方法的上述弱点?

4个回答

重要的是维护无论您是重用现有代码还是编写自己的代码,只有在某个地方有人理解代码并能够使其在编译器和平台的演变方面保持稳定时,您才能获得良好的安全性。拥有没有错误的代码是最好的,但实际上您必须依赖次优,即在短时间内及时修复错误(尤其是可用于恶意使用的错误,也称为漏洞)。

如果您编写自己的代码,那么维护工作完全依赖于您自己的肩膀。而且这项工作可能非常耗时。例如,如果您决定编写和维护自己的 SSL/TLS 库,并在生产中使用它,那么您必须了解加密实现的所有特性,特别是对侧信道攻击的抵抗力,并且您必须密切关注已发布的攻击和对策。如果您在时间和能力方面有足够的资源,那很好!但是维护成本也不容小觑。从长远来看,重用现有库,尤其是广泛使用的开源库,可能会更便宜,因为维护是由其他人完成的,并且广泛使用确保了外部审查。作为奖励,如果有一半的世界共享外部库中的安全漏洞,您就不会受到责备。

总而言之,问题不在于代码重用,而在于维护工作重用。

(我独立于编写自己的代码的伟大教学质量来编写所有这些。我鼓励你进行自己的实现——但肯定不是为了在生产中实际使用它们。这是为了学习。)

更是如此。

安全码很棘手即使您是受过训练的密码学家, 密码学代码也非常困难- 如果您不是,就不可能正确。

如果在这么多重要的软件包和公司中有这么多严重的错误 - 是什么让您认为*您能够做得更好?

* 当然,除非这是您的特定专业领域,并且安全功能是您产品的核心......

有趣的问题!我想从概率的角度来回答这个问题,而不是从最佳当前实践的角度来回答。

虽然 Thomas 和其他人提供了很好的答案,但我认为他们没有触及核心问题——即“在实践中,独特(或较少使用的)代码比流行代码更具弹性”。请注意,我故意不使用“比流行代码更安全”。归结为“通过默默无闻的安全工作”的特殊情况?

而且(我知道这不会是流行的答案)我认为当我们用“弹性”替换“安全”时,答案实际上可能并不总是被普遍接受“从不!”

它表明它可能不太安全(意思是:很可能您自己的安全代码比以前经历过许多攻击并且由比您更聪明的人修复的流行代码更容易/更快地破解)。

但是,除非您是大型/受欢迎的站点,否则如果潜在的破解者不能重用破解您所花费的代码/努力,那么您对他们的兴趣就会大大降低,而且这种努力并非微不足道(意思是,您的网站不会崩溃自动参数非验证/SQL注入探测)如果您被专门针对(工业间谍活动等),这显然不起作用,但当时绝大多数攻击实际上似乎是针对流行软件的自动探测。

因此,如果问题不是“哪个更安全”,而是“哪个不太可能被破解”,那么答案实际上可能是“取决于情况”。这里有几个例子:

示例 1:想象一下 Microsoft windows 8.1(或现在流行的任何东西)计算机,目前没有已知的安全漏洞,购买但从未更新,连接到 Internet。还可以想象几十年前的 Windows 3.11,带有 winsock,从未打过补丁,已知有数百个安全漏洞,连接到 Internet。两者的使用方式相同。出于讨论访问质量的目的而忽略...问题是,哪个会更早被破解?

虽然很明显 3.11 的安全性要低得多,但几乎没有任何针对它的漏洞利用。因此,在 3.11 遇到一些能够在其上运行的古老漏洞之前,很可能会有大受欢迎的 0-day 漏洞攻击 8.1。

示例 2:假设您在一台 Web 服务器上安装了最新的 Joomla CMS,当前没有已知的漏洞利用,并且手工制作的 perl 脚本在执行 CMS 类似的事情,具有已知的可利用漏洞(但对于当前可用的自动化测试没有可疑的漏洞)。一年后,哪个更有机会被利用?

虽然轶事证据表明,在过去几十年我遇到的几十个(到数百个)案例中,大多数情况下流行的软件都被利用了,而过时的软件至今仍不受干扰地继续运行。

另一个值得考虑的事情:

  • 如果流行的软件会自动更新(或者管理员总是及时更新),那么这种流行代码的弱点就会大大减少(但并没有消除,由于 0-day 和未发布的漏洞利用),因此具有很大的优势
  • 相反,如果软件不接受维护,那么不受欢迎的软件(比如自己编写的)实际上可能不太容易出现问题
  • 责备 - 使用流行的软件通常可能是有利的。如果半个世界都受到影响,那么你受到的责备几乎不会像你是一个程序员那样受到责备。如果使用金钱,这一点尤其重要。在安全性较低但能够转移责任的情况下,通常“更好”,而不是更安全但在漏洞利用确实受到攻击时必须自己承担成本。
  • 工作 - 其他人已经提到,流行软件在​​绝大多数情况下会自行修复,您只需要更新 - 这比自己实际查找和修复错误要少得多(但仍需要一些维护)
  • 自写软件的另一个优势通常是减少大量代码(导致更少的错误),因为您通常不需要大部分功能或可定制性。例如,人们会使用 Joomla,即使他们需要的只是简单的“模板新闻网站”,实际上这可以用几十行代码来完成。即使您作为程序员的能力不如在流行软件上工作的有成就的人的一半(因此您每行代码的错误数量明显更多),由于具有数量级,您通常仍然可以大获全胜(或很少!)编写/维护的代码更少

简单的答案是:不要推出自己的安全性。

这有两个部分。算法和实现。

至于算法,创建自己的加密算法是可怕的。即使您精通密码学领域,您仍然无法创建新算法。除非您拥有该领域的专家团队,否则您不会推出自己的算法。为了说明这一点,请查看一些最近被破解的算法以及它们是如何被破解的。表面上看起来很棒的东西有我从未想过的弱点。

至于实现,创建自己的好算法实现并不像创建自己的算法那么可怕,但除非你是这方面的专业人士,否则不要这样做。实现中的一个错误,核心算法有多好并不重要。在这种情况下,您要问的问题是,您是否比许多致力于组建顶级安全库的专家更好。

更有可能的是什么。您可以推出自己的算法和实现而没有任何错误或弱点,或者您使用的算法和实现将有一个后门?

如果您可以创建一个完美的算法并实现,那么后门的风险将不是问题。但这不现实。

还有一个你想向你的经理/股东/等解释的问题?某个顶级可信软件包中存在后门,整个行业都在运行,或者您个人尝试提高安全性的尝试严重失败。我个人更愿意解释说,我做出了整个行业的专业人士做出的选择,而它失败的唯一原因是一些影响甚至跨国公司的大规模问题。

也就是说,我同意 Thomas 的观点,即尝试自己动手是一种很好的学习体验,只要它永远不会看到生产的光芒。