65.9K
CodeProject 正在变化。 阅读更多。
Home

401 和/或 403 以及一个关于安全的 RESTful 故事

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (4投票s)

2019 年 7 月 4 日

CPOL

3分钟阅读

viewsIcon

6367

401 和/或 403 以及一个关于安全的 RESTful 故事

在设计 RESTful 服务时,不可避免地会遇到使用哪个 HTTP 状态码的问题。 然而,关于 401 和 403 状态码存在一些微妙之处。 你可以在这里和那里读到建议使用

  • 401 用于未提供访问令牌或访问令牌无效的情况
  • 403 用于访问令牌有效,但需要更多权限的情况

人们会遵循这些建议,而没有考虑到安全问题。

问题在于,这种实现可能会泄露敏感信息。 这是我对上述文章的回复。 在密码学中,这被称为 预言机,可能导致 非常严重的攻击

如果攻击者在多次失败的尝试(返回 401)后看到 403 状态码,这意味着攻击者尝试的任何内容都通过了身份验证阶段,但未能通过授权。 恭喜,他们刚刚找到了有效的凭据集(或令牌等),而你的系统以“明文”形式告知了他们。 这类似于 “用户名或密码无效”的最佳实践(不要阅读像 这篇文章这样的内容!)。

如何避免这个问题? 坚持使用一个状态码(例如,403)来表示两种情况(身份验证失败和授权失败),避免过于友好(或对客户端友好)。 你可以记录事件并向客户端返回一个唯一的请求 ID。 如果真正的客户端报告了问题,该请求 ID 应该有助于在日志中找到更多详细信息。 当然,还要跟踪/监控所有身份验证/授权失败,以进行异常检测。

现在是有趣的部分,将上述所有内容作为数学证明。 假设一个系统中,可能的凭据的最大数量为 N,注册用户数为 M,其中 K 个用户有权访问攻击者试图暴力破解的特定资源,N>M≥ K。 让我们考虑以下命题/事件

  • A - 通过访问给定资源来猜测凭据。
  • B - 系统设计为返回:HTTP 200 用于具有访问权限的有效凭据,HTTP 403 用于没有访问权限的有效凭据,HTTP 401 用于无效凭据。 为了简单起见,我们可以说 B={200}∪ {403}∪ {401}
  • C - 系统设计为返回:HTTP 200 用于具有访问权限的有效凭据,HTTP 403 用于没有访问权限的有效凭据或无效凭据。 或者 C={200}∪ {403}

换句话说

  • B 给定 A 的基数是:K 个 HTTP 200 的可能情况,加上 M-K 个 HTTP 403 的可能情况。 总计为 M
  • C 给定 A 的基数是:K 个 HTTP 200 的可能情况,这也总计为 K

现在让我们计算概率

P(A | B)=MNP(A | C)=KN

显然(因为 M ≥ K

P(A | B) ≥ P(A | C)

这意味着,像 B 这样设计的系统会给攻击者更大的机会来猜测凭据。 显然,如果所有注册用户都具有访问资源的权限(即 K=M),则无关紧要。 讨论结束!

后记: 我计算概率的方式可能看起来有点粗略。 如果需要更数学化的版本,请访问原始帖子

© . All rights reserved.