使用存储过程保护密码哈希?

信息安全 密码 密码管理 sql注入
2021-08-26 00:57:09

我在考虑最近(似乎是每周一次)的安全漏洞,我们已经看到数百万个密码哈希被泄露,我想知道如何保护他们的网站免受密码转储,即使黑客发现了 SQL 注入漏洞。

如果网站用来登录数据库的用户拥有更有限的权限怎么办。假设用户在所有非关键数据上都拥有正常的完全权限(CRUD)。但是,如果用户被拒绝对存储登录哈希、安全问题等的表进行所有 CRUD 操作,并且只能在该表上运行存储过程,该怎么办。假设这些存储过程从未将密码散列返回给应用程序层,而是将散列传递给过程,过程将返回一个布尔值,指示是否存在匹配项。

在我看来,这种设置将完全消除通过 SQL 注入进行密码哈希转储的可能性。此设置是否提供额外的安全性,是否可取?


更新

请参阅此问题以获取更多详细信息:

从安全的角度来看,将 ASP.NET 网站的数据库服务器用户限制为仅在存储过程上执行是否值得?

2个回答

您描述的方案在概念上类似于制作一个专用的密码验证服务器(本地服务器,不向全世界开放),它有自己的、完全不同的数据库来存储散列密码。这可以工作。实际上,当用户帐户被映射到例如 Active Directory 服务器或本地 Unix 帐户时,您已经在“系统集成”的幌子下拥有它。

为此,在数据库中使用存储过程依赖于数据库强制执行适当的隔离——这是一个有点冒险的赌注,因为您正在设想攻击者可以包含他自己的 SQL 语句的情况。

看待问题的另一种方式是假设数据库受到损害。如果数据库被攻破,得到了密码表,如何让数据变得毫无意义,从而降低攻击的价值呢?

首先,您当然希望使用强大的加密散列算法(bcrypt、scrypt 等)。您想使用随机盐来降低有效使用彩虹表的能力。您还可以使用胡椒机制并通过另一个服务器或硬件安全模块 (HSM) 使用分离,如果没有胡椒,从哈希列表中获得任何有意义的东西的可能性将大大降低。您可以使用仅存在密码表的锁定服务器在较小程度上完成此操作,确保请求服务器和您的密码验证服务器之间存在适当的加密和身份验证。