我的朋友刚刚问我:“当我们只将各种密码存储在我们的私有 Git 服务器中时,为什么直接将各种密码直接放在程序的源代码中那么糟糕?”
我给了他一个答案,强调了几点,但觉得它不够有条理,并认为创建一个规范问题可能是有意义的。
此外,在源代码中不存储密码与最小权限原则和其他信息安全基础有何关系?
我的朋友刚刚问我:“当我们只将各种密码存储在我们的私有 Git 服务器中时,为什么直接将各种密码直接放在程序的源代码中那么糟糕?”
我给了他一个答案,强调了几点,但觉得它不够有条理,并认为创建一个规范问题可能是有意义的。
此外,在源代码中不存储密码与最小权限原则和其他信息安全基础有何关系?
在我看来,不在 Git(或其他版本控制)中存储密码是一种约定。我想人们可以决定不以各种结果强制执行它,但这就是为什么通常不赞成这样做:
我不能说与信息安全相关的每种模式都是好的,但在破坏它们之前,考虑您的威胁模型和攻击向量总是一个好主意。如果这个特定的密码被泄露,攻击者使用它来损害公司的难度有多大?
一、非安全原因:
密码更改工作流程
密码的变化独立于软件应用程序代码。如果 DBA 更改了数据库密码,那么开发人员必须更新代码、获取新的构建并发布到生产环境并尝试计时,这是否有意义?密码是运行时配置工件,而不是开发工件。它们应该通过配置文件、环境变量或您正在使用的任何配置范例注入。
授权范围
通常,版本控制系统提供授权控制,因此只有授权用户才能访问它。但是在存储库中,权限通常要么是读/写,要么是只读的,或者可能是 GitHub 提供的一些花里胡哨的东西。您不太可能找到让开发人员获取源代码而不是密码的安全约束。如果您可以克隆存储库,则可以克隆存储库。时期。在许多环境中,开发人员无法完全访问生产环境。有时他们对生产数据库具有只读访问权限,有时没有访问权限。如果开发人员通常可以访问,但您不希望所有实习生、新员工等都拥有访问权限,该怎么办?
环境
如果您有多个环境,例如开发环境、QA 环境、登台和生产环境,该怎么办?您会将他们所有的密码存储在版本控制中吗?应用程序如何知道使用哪一个?该应用程序需要有一种了解环境的方法,这最终将成为一个配置设置。如果可以将环境名称作为配置设置,则可以将数据库密码作为配置设置(连同连接字符串、用户名等)
历史
正如其他人所提到的,版本控制旨在保留历史记录。所以旧密码仍然可以检索,这可能不是最好的选择。
妥协
我们有多少次在新闻头条看到某些产品的源代码被泄露给全世界?源代码是版本控制中的任何内容。这可能是不将密码放入版本控制的首要原因!
然而...
也就是说,密码需要存储在某个地方。以上问题所暗示的不一定是它们根本不应该存储在版本控制中,而是它们不应该存储在版本控制中的产品源代码存储库中。有一个单独的 repo 用于配置管理、操作等是非常合理的。关键是在安全凭证方面将操作与开发分开,不一定要完全避免版本控制。
此外,对于非生产环境,我已将外部系统的密码和 API 密钥作为默认值存储在产品源代码中的配置文件中。为什么?为了让开发人员在签出代码时更加轻松,他们只需构建并运行它,而不必去获取额外的配置文件。这些证书很少更改,不会导致任何商业机密。但我永远不会对生产机密这样做。
所以底线是......这取决于。
请务必记住,建议必须根据您的用例量身定制。例如,美国国家安全局(NSA)为保护他们未雨绸缪的所有零日漏洞而采取的安全保障措施,应该比为保护猫图片发布网站上的投票而采取的安全保障措施要严格得多。在一个极端情况下,我可以想到一个将密码/令牌/等保存在私有 git 存储库中的示例可能是合理的:
如果该存储库仅由一个人访问,并且应用程序不存储任何有价值的信息。
在这种情况下,去镇上!请记住@d33tah 在他的回答中所说的内容 - 从 git 存储库中清除内容可能非常困难(毕竟,重点是永远保留所有内容的历史)所以如果你决定在路上与更多人协作,但不希望他们获得对您所有系统的完全访问权限,那么您的手会有些头疼。
这就是它真正归结为的原因。您的代码存储库在某种程度上是“公共的”,即使只与协作者共享。仅仅因为您想要与某人协作并不意味着您想要让他们完全访问您的基础设施(当您将密码/令牌放入代码存储库时实际上会发生这种情况)。很容易想到“是的,但我信任与我合作的人!”,但这只是看待这个场景的错误方式,原因有很多:
简而言之,良好的安全性在于具有分层防御。大多数黑客攻击的发生是因为黑客发现了一个领域的弱点,从而使他们能够利用另一个领域的弱点,从而导致其他地方,最终使他们获得丰厚的回报。为您的情况制定尽可能多的安全保障措施是确保整个事情安全的原因。这样,当备份硬盘从您的办公室走出来时,您意识到它没有加密,您不必问“这是一次有针对性的攻击吗?我现在是否必须更改我在各处拥有的每一个凭证,因为它们都在那个备份驱动器上的 git 存储库中?”。同样,根据您的情况,这可能不适用于您,但希望这有助于解释在什么情况下这可能很重要。
将机密(密码、证书、密钥)与源代码分开,可以根据不同的策略管理源和机密。就像,所有工程师都可以阅读源代码,只有直接负责生产服务器的人才能访问机密。
这使开发人员的生活更轻松,因为他们不受保护机密所需的严格安全策略的约束。可以使源代码控制策略对他们来说更加方便。