← 返回信息流
AI 资讯Hacker News·3 天前

我们为何不信任数据库进行身份验证

原标题:Why We Don't Trust the Database with Authentication

速览

文章指出,将身份验证逻辑置于数据库内会带来安全风险和性能瓶颈。传统上,许多应用依赖数据库用户权限管理认证,但这破坏了职责分离,且难以适配现代复杂的安全策略。作者建议采用独立的身份验证服务或中间件,以提升系统安全性和可扩展性。该观点反映了后端架构设计中的最佳实践变迁。

AI 深度解读

背景

在构建API时,许多开发者会不自觉地引入一个危险的隐含假设:数据库是最终真相来源(source of truth)。如果一个记录存在于数据库中,应用程序往往将其视为权威。然而,这种“数据库即认证”的思维模式可能带来严重的安全漏洞。Sturdy Statistics 公司在其工程实践中明确提出“纵深防御”(Defense in Depth)理念:在每个层级都努力防止故障,但设计每个层级时又假设其他层级可能失效。当涉及API认证时,将数据库作为身份的唯一仲裁者,实际上是一种伪装成标准实践的关键脆弱性。

核心内容

绕过攻击:SQL注入如何导致系统级访问

假设一个典型的API密钥处理方式:生成随机密钥,哈希(如SHA-256),将哈希与org_id一起存入api_keys表;请求到来时,哈希提供的密钥并查找匹配行。这看起来安全,因为数据库只存哈希,不存明文。但攻击者一旦在应用程序其他位置发现盲SQL注入漏洞,就可以执行以下操作:

  1. 注册合法账户,生成自己的有效API密钥(已知明文)。
  2. 利用SQL注入执行UPDATE语句,将自己的密钥哈希复制到目标受害者行的哈希字段中。
  3. 攻击者用自己(有效)的密钥发起请求,API中间件哈希该密钥,在受害者行中找到攻击者粘贴的哈希,从而授予访问权限。

此时,攻击者绕过了整个API安全边界和基于密钥的租户隔离层。因为应用程序盲目信任数据库中的哈希记录,一次简单的数据库写入就导致了完整的租户接管。

解决方案:密码学绑定(Cryptographic Binding)

Sturdy Statistics 不存储简单的API密钥哈希,而是使用服务器端密码学胡椒(Pepper)——一个高熵、用TPM密封在后端内存中的秘密——来计算HMAC-SHA512签名。关键点:不仅签名密钥本身,还签名密钥的结构上下文:

Stored Hash = HMAC-SHA512(Pepper, api-key-id || rotation-version || org-id || secret)

其中:

  • api-key-idrotation-versionsecret 从客户端传入的令牌中解析。
  • org-id 严格从请求URL路径参数中提取。
  • 数据库提供存储的哈希以进行比对,同时记录api-key-idrotation-versionorg-id。这样,秘密和存储哈希各出现一次,其他标识符在两个位置存储,形成“双重记账”以检查一致性。

如果攻击者篡改数据库,将组织A的哈希交换到组织B的行中,认证中间件会从URL路径中提取组织B的org-id并注入HMAC计算。由于哈希编码了错误的org-id,签名被拒绝,攻击者被锁定。此外,Pepper仅存在于后端内存中,从不接触数据库,即使攻击者拥有完整的数据库读写权限,也无法在没有Pepper的情况下铸造或修改密钥。

回滚抵抗(Zombie Keys)

rotation-version 被纳入哈希,将签名绑定到密钥生命周期的特定纪元。如果密钥被泄露并轮换,旧版V1哈希失效。但攻击者可能通过数据库写入,将活跃行中的哈希改回V1版本,并将rotation-version回退到1。为防止此情况,Sturdy Statistics 在数据库层使用触发器(TRIGGER),强制rotation_version列只能单向递增(one-way ratchet)。当攻击者尝试回滚版本时,数据库架构本身拒绝该事务。即使攻击者拥有数据库写权限和已过期的密钥,也无法复活该密钥。

多租户隔离:四层验证

在多租户环境中,租户间数据泄露是常见安全故障。Sturdy Statistics 在每次请求的整个生命周期中重复强制租户检查:

  • 路由层:每个请求路径中明确声明租户(作为路径参数),确保在应用代码执行前路由基础设施知道访问的逻辑边界。
  • 认证层:API密钥验证通过密码学直接绑定到org-id
  • 应用层:每个读写操作强制执行租户作用域,业务逻辑函数不接受裸标识符,需要授权租户上下文。
  • 数据库模式层:作为最终保险,使用数据库触发器在最底层强制执行租户隔离。即使应用层逻辑错误尝试跨租户写入,模式也会拒绝。

零停机密钥轮换

由于明确控制了哈希和数据库模式的精确机制,Sturdy Statistics 将零停机轮换直接构建到架构中。api_keys表包含prev-hash列和grace-period-expires-at时间戳。用户轮换密钥时,生成新秘密,增加旋转版本,计算新主哈希。旧哈希降级为prev-hash,并设置严格生存时间(如24小时)。在此期间,后端检查可授权任一密钥。这允许分布式客户端系统异步更新环境变量,而不丢失任何合法请求。为防止攻击者通过重写宽限期复活已过期密钥,另一个触发器(原文未明确细节,但指出解决方案)被用于保护。

关键要点

  • 不要信任数据库作为认证的唯一权威:数据库的读写漏洞(如SQL注入)可以直接绕过API安全边界,导致租户接管。
  • 密码学绑定(Pepper + HMAC):将密钥的上下文(org-id、rotation-version)一起签名,使数据库中的哈希依赖于后端独有的Pepper,攻击者无法伪造或篡改。
  • 双重记账org-id等标识符既在客户端令牌中,又在数据库记录中,认证时交叉验证,防止哈希被跨租户移动。
  • 回滚防护:通过数据库触发器强制旋转版本单向递增,拒绝回滚操作,即使攻击者有数据库写权限也无法复活已轮换的密钥。
  • 纵深防御四层验证:路由层、认证层、应用层、数据库模式层,层层强制租户隔离,防止单点故障。
  • 零停机轮换:使用prev-hash和宽限期机制,使客户端可以异步更新密钥而无需停机,同时通过触发器防止攻击者滥用宽限期。

意义与影响

这篇文章揭示了现代API安全中一个普遍但被忽视的脆弱性:将数据库作为认证的最终仲裁者。许多开发者在设计认证系统时,默认信任数据库的完整性,却忽略了数据库本身可能被攻破(如SQL注入、管理员权限滥用等)。Sturdy Statistics 提出的解决方案——密码学绑定、回滚防护、多层租户隔离——为行业提供了可操作的纵深防御实践。

意义在于:

  • 打破“数据库即真理”的思维定式:认证系统的安全性不应依赖于数据库的安全,而应通过密码学将其与数据库解耦。
  • 可落地的技术方案:HMAC + Pepper 结合数据库触发器,既不需要复杂的基础设施变更,又能有效抵御SQL注入、回滚攻击等常见威胁。
  • 多租户安全的强化:四层验证确保即使某一层失效,其他层仍能阻止数据泄露,符合OWASP推荐的最佳实践。
  • 易用性不牺牲安全:零停机轮换机制解决了密钥管理中的核心痛点,使安全措施更容易被采用,而不是被绕过。

对开发者而言,这篇文章提醒我们:在设计任何依赖于数据库的认证系统时,必须考虑“数据库被完全控制”的极端场景,并通过密码学绑定和分层防御来消除这种风险。

查看原文 →blog.sturdystatistics.com