关于安全性:我应该在何处以及如何存储租户数据库密码?

Where and how should I store tenant DB passwords?

我有一个基本的Web应用程序,它为系统的每个"租户"使用一个单独但相同的数据库。有一个主数据库,其中包含一个将每个用户链接到其数据库副本的表。

目前,所有租户数据库连接细节都以明文形式存储在主表中。我知道它不好,只是一个临时措施,所以我可以继续写功能。

我只能想出两种方法来保护连接细节(见下文),这两种方法似乎都有缺陷,所以我希望得到一些建议,如果你不介意的话,请?

  • 使用某种形式的salt和hash方法来存储密码,将密钥存储在应用程序可以访问的本地文件中。

  • 使用第三方服务(如Amazon KMS)加密整个主数据库。

  • 我认为第二个选项是最安全的,但是我依赖于一个我不完全理解的DB插件和一个会降低性能的第三方服务。

    我对这两种方法的问题是,如果有人能够向我的代码中注入一个select查询并访问主表(仅供参考,所有查询变量都绑定为参数),不管我使用什么方法,它总是会解密密码。这是否总是我们所接受的情况,或者是否存在另一个安全层来阻止潜在的攻击者?

    谢谢!


    好问题。不确定我有答案,但有几个考虑:

    首先考虑解决方案(1)——密码散列。

    如果主数据库中存在SQL注入或类似漏洞,则不会导致解密密码。相反,它允许黑客获取密码的散列值,他可以尝试通过暴力或相关攻击来反转密码。如果您以错误的方式进行密码散列,那么攻击者很可能会成功。另一方面,如果您使用具有良好参数的bcrypt(/scrypt/argon2/pbkdf2)等算法,那么您有更好的机会抵制它。

    此外,如果攻击者可以以某种方式将SQL查询注入主数据库,那么他不仅可以从中读取,还可以对其进行写入(您可以尝试通过使用具有写访问权限的DB帐户的读取查询来降低此风险)。如果攻击者可以写入,那么他可以用自己选择的密码覆盖真正的密码,所以他还是赢了。

    查看第二个解决方案,我相信您是正确的,注入漏洞将被传递给第三方服务。在这种情况下,加密对您没有帮助。但是,如果您也正确地散列密码,那么攻击者的场景将与场景(1)相同。因此,您从第三方服务中获得的信息并不能减轻您的担忧。

    所以一般来说,我说你必须要做的解决方案(1)。然而,问题真的变成了你还能做什么?这是一个很长的对话。一个简单的答案是双因素认证,但这可能会让用户恼火。另一方面,只有当用户来自一个新的IP地址或一个结合了安全性和可用性要求的新设备时,才可以考虑双因素身份验证。