对于不存在的REST资源,何时返回404以及何时返回403?
我对这个逻辑很熟悉,如果你想使用用户名和密码对某人进行身份验证,那么无论用户名是否被找到,或者密码错误,你都应该返回相同的错误。这个想法是,如果你返回单独的“用户未找到”和“用户发现,但密码错误”错误,攻击者可以尝试所有用户名,并找出哪些用户名是有效的,然后将他们的字典攻击集中在那些用户名。对于不存在的REST资源,何时返回404以及何时返回403?
使用REST服务,我有一个只有特定用户可以访问的资源,我们称之为/foo/{id}
。因此,有多种情况:
用户试图访问
/foo/4
,他们有机会,他们显然得到了200响应和资源。用户试图访问
/foo/3
并且它不存在。 (我不知道他们是否有权访问它,因为它不存在。认为Facebook上不存在的照片,照片只有当它存在时才拥有所有权信息。)A用户尝试访问
/foo/4
,它存在,但他们没有访问权限。
所以我的问题是,什么样的返回代码返回情况2和3?至于我可以看到有选项:
返回404的情况下2,和403的情况下3.但是,这意味着攻击者可以找出哪些对象存在,类似于密码例如在第一例。
对于所有示例,毕竟,从用户的角度返回404,如果他们列出了他们有权访问该资源的所有资源,则他们无权访问的资源“不存在”不在列表中。
返回403为所有示例。
你会做什么?这里的标准是什么?
这是什么标准?
一个希望“隐藏”禁止的目标资源的当前存在可能,而不是用的状态代码404(未找到)响应的原始服务器。
有趣的是,在HTTP/1.0,这是围绕
转身如果服务器不希望提供给客户这些信息,状态代码403(禁止)可以用来代替。
你应该知道403和404有different default caching behavior。
在审查错误响应小心恶意用户无法收集有关系统的任何潜在的敏感信息从状态代码返回。例如:采用租户ID参数的API搜索,并返回无结果的HTTP 404响应,以及如果租户ID不存在,则返回HTTP 500响应。攻击者可能会利用此信息来确定租户ID是否有效。一种解决方案是捕获提供的租户ID不存在时抛出的异常,并返回带有错误响应的HTTP 404状态码。
请注意,状态码不是可被利用的响应的唯一部分;如果您要完成对齐状态代码的工作,则还应该确保消息正文和标题不会给任何东西带走任何东西,the timing of the response不会让节目脱颖而出,依此类推。
在我们的项目中,我们继续进行选项之一:
404
- 如果资源的物理丢失
403
- 如果用户没有权限访问
与ID猜测的问题被解决使用不透明的标识符,如GUIDs
:
/foo/08490cee-c5a1-4ea5-a00e-1a488fd58044
不可猜测的标识符是因为否则攻击者可以简单地添加或减少ID号码,甚至可以学习他们不应该知道的事情,例如创建了多少个实体对象。还要记住 - 数据库主键可能仍然是整数。
除此之外,我不确定这里是否有任何标准。您可以继续使用适用于您业务领域的三种方法。
如果资源有一个所有者,或多个业主,这可能帮助:
如果资源确实存在,但用户不应该被允许看到它,在内部把它想“资源确实存在 - 但不适合你!“,因此我会返回404.
正如你所说,小心你返回403的地方,因为它可能会暴露内部元数据。