REST API 中的请求签名(消化请求正文)是否必要?

信息安全 Web应用程序 休息
2021-08-12 06:00:03

我目前正在进行一场辩论,我想知道社区对此有何看法。

  1. 我们看到只需要基本身份验证(可能是 HTTP)或 OAuth 的 REST API。

  2. 我们看到 REST API 也需要签名;包含秘密,时间戳,也许是随机数。

  3. 我们偶尔会看到 REST API 也需要请求参数(以特定方式组装)包含在签名中。

数字 3 提供了全面的安全性(尽管在现实和实践中前者有很多问题吗?),但是,它增加了更多的实现复杂性 - 以特定方式组装请求参数创造了一个很大的机会来搞砸事情,而你可以告别“快速测试”API。

我的安全负责人会说“选择 3 号,白痴”,但我的可用性负责人说“这是一个完整的 PITA,2 号在现实世界中就足够了,如果使用得当 - 即通过 https - 没有什么可出错的” .

2个回答

从服务器,您可能需要两件事:

  1. 确保发送请求的客户确实是他们声称的人;
  2. 能够向第三方证明发送给定请求的人确实是特定的客户实体。

实现第二个目标或多或少需要数字签名。对于第一个目标,简单的身份验证就足够了;在 SSL (HTTPS) 中播放的 HTTP“基本身份验证”就足够了。您的“类型 2”方法是一种依赖于客户端证书的身份验证;另一种同样好的方法,并且更容易激活,是在 SSL 级别使用客户端证书(SSL 库然后自己处理 nonce-timestamp-signature 业务)。

方法 1 或 2 都不会产生可在诉讼期间使用的证据。身份验证使服务器相信正确的客户端位于线路的另一端,但服务器没有得到任何可以说服法官的信息。为此,您确实需要在请求本身上签名,即您的“方法 3”。并不是说方法3“更安全”;相反,方法 3 提供了一个附加功能,它可能对您的特定情况有用,也可能没用。

另外,请注意,签名请求并不能完全取代身份验证,即使只是因为重放攻击

如果使用 HTTPS 与服务器通信(仅使用受信任的证书!),则没有直接理由使用任何更复杂的方法。一个简单的纯文本密码基本身份验证就足够且安全。

如果通信通道不受信任,例如,如果允许公司中间人 SSL 代理或不受信任的证书,则请求的所有部分都应包含在“签名”中,包括某种形式的重放保护。此外,“签名”不得泄露认证秘密。

Thomas 提出的关于客户请求可证明性的观点是一个很好的观点。但是,我遇到的大多数 REST API 中的“签名”根本不是签名——它是一个对称的身份验证器,对可证明性没有任何帮助(相同的身份验证器可以而且必须由服务器计算)。

因此,除非您实际上有客户的客户证书,否则确保客户确实是他们声称的人的方法是无关紧要的。