对于 REST 服务,500 响应或特定错误代码是否更安全?

信息安全 http 休息
2021-08-21 12:47:54

我正在构建一个 REST API 来为我的客户和第三方合作伙伴存储安全敏感数据。

每个请求都使用特定数据的 HMAC 进行验证,该 HMAC 键入在用户登录后短时间内分配的临时密钥上。当然,一切都通过 TLS 运行。每个请求都会被记录,连同返回的任何数据的键,以及如果由于某种原因没有阻止请求而本应返回的任何数据的键。

如果数据不存在,或者某个位置的数据可能被特定用户读取但未更新,或者如果更新请求格式错误,服务器是否应该返回有意义的错误消息?

  1. 如果用户无权执行某项操作,则应返回 401 或 403 响应,表示请求因缺少执行该操作的权限而失败。在数据格式错误或预期数据类型不匹配(将字符串发送到 int 字段等)的情况下,可能会使用其他响应代码。基本上,遵循良好的 REST/HTTP 实践并记录所有内容,但除了关于出错的基本提示之外,不要向用户提供任何信息。

  2. 永远不要向任何人提供任何信息,以防它以某种方式被用于攻击系统。只返回 500 错误,没有任何类型的描述。对于是否返回 404,或者是否应该返回空响应或 500 错误,存在一定程度的分歧。如果第三方开发人员遇到这些响应,并且不明白为什么,他们必须联系我们公司,让某人查看日志并解释如何正确提出请求。

关于哪种方法最有意义,是否有人“从战壕”中获得经验?特别值得关注的是如何平衡安全性与可用性和支持请求。

3个回答

简洁版本:

提供足够的信息以支持您的应用程序的合法用户,但仅此而已。

长版:

首先,对此没有单一的答案,因为它取决于应用程序的上下文。如果您正在为您的产品发布一个开源 API 以允许人们编写客户端,那么您希望倾向于提供有用的反馈,以便他们可以调试他们的代码并编写有用的错误处理程序。如果您要发布闭源客户端软件以与闭源服务器交互,那么您可能会受到更多限制,因为您只会影响自己。

其次,RESTful 模型部分暗示您将返回具有语义含义的 HTTP 代码(例如,404 表示“未找到”,而不仅仅是 500 表示所有内容)。当然,REST 只是一种做事方式,所以如果你不这样做,REST 审计员不会敲你的指关节,但是如果你使用的是模型,你应该考虑它有理由被设计成它是。

第三,您可以拥有的最重要的安全重点是错误消息的内容,而不是能指。返回 404、403、405、502 或 503 很好,因为它可以帮助端点大致确定出了什么问题。另一方面,从您的 Tomcat 服务器返回堆栈跟踪是多余的 - 它可能是默认设置,所以要小心!

最后,我“从战壕中”获得的经验正如我所描述的那样:返回正确的 HTTP 错误代码,但不要对此充满诗意,“503”表示“服务不可用”,仅此而已。对于不是 HTTP 级别的问题,我们返回 200 和一个简短的应用层错误代码。代码是数字的,可以在 API 中找到,因此确实为“攻击者”提供了一些信息——这里他们的密码错误,这里他们有太多的并发连接,这里他们有“令人反感的内容”。是的,这为攻击者提供了一种映射系统的方法。拥有一个可以由合法用户调试并为合法用户调试的系统的价值超过了通过使用通用返回值混淆错误所获得的安全利益。例如,我'通过在错误代码中将其提供给他来做到这一点

我会避免错误401,因为它会触发浏览器显示 HTTP 身份验证登录框。这很烦人并使您的用户感到困惑。

除此之外,返回您想要的任何错误代码,请记住某些客户端会根据您的响应代码执行某些操作。

例如,a500403可能会阻止您的响应被搜索引擎索引,而 a200可能不会。错误代码本身并没有真正披露任何安全方面的信息。范围内的任何内容都4xx表示“客户端做错了”,而5xx范围内的任何内容都表示“服务器做错了什么”。

如果提供宁静的服务,我会结合这两种选择。但我只返回 401 或 403(不区分它们)并简单地为 404 和 500 生成一般错误,我会使用 200 代替自定义消息而不是 404 或 500。