在我的 Angular 应用程序中,我在 URL 中使用 MongoDB id。这有什么安全风险吗?
我应该使用计数器,然后在我的数据库中有某种集合将该计数器链接到实际 ID 吗?所以mysite.com/story/56ede7fsdfdsfdsfs2a7283
我会使用mysite.com/story/32
?
在我的 Angular 应用程序中,我在 URL 中使用 MongoDB id。这有什么安全风险吗?
我应该使用计数器,然后在我的数据库中有某种集合将该计数器链接到实际 ID 吗?所以mysite.com/story/56ede7fsdfdsfdsfs2a7283
我会使用mysite.com/story/32
?
除了根据服务器向用户公开创建时间之外,我想不出任何真正的安全风险来公开 mongoDB id(相对于其他一些计数器 id)。拥有 mongo 主键与其他一些唯一键(如计数器)不应该在曝光方面产生影响。
当然,您应该知道,mongo_id
包括:
- 一个 4 字节的值,表示自 Unix 纪元以来的秒数,
- 一个 3 字节的机器标识符,
- 一个 2 字节的进程 ID,以及
- 一个 3 字节的计数器,从一个随机值开始。
并且您可能不想向您的用户公开这些信息(例如创建时间)。
因此,当您有 id 56ede7f0dfdsfdsfs2a7283
(其中有一个非十六进制数字s
并且最后似乎缺少一个十六进制数字时 - 它应该是 12 个字节或 24 个十六进制(0-9a-f)数字,所以我有用 '0' 替换了 's'),我可以看出56ede7f0
它是在2016-03-19T23:59:44.000Z
. (参见例如:https ://steveridout.github.io/mongo-object-time/或尝试:ObjectId("56ede7f0dfd0fd0f20a72830").getTimestamp()
在 shell 中)。
OWASP提到简单地使用任何类型的直接标识符都可能是不好的,正如Top 10 2007-Insecure Direct Object Reference和Top 10 2010-A4-Insecure Direct Object References条目中所解释的那样。能够弄清楚如何利用这种直接引用的攻击者将拥有比他们应该拥有的更多的权力。
正如您在此处所问的,OWASP 实际上建议使用索引值,但这些可能会带来自己的问题。如果攻击者发现身份验证或权限提升漏洞,则为攻击者提供一种按顺序访问所有数据的简便方法可以让他们轻松读取、更新甚至删除整个数据库。
在现实世界中,这样的事情曾经发生过。就像使用密码重置页面中的简单主键从服务中获得的几个电子邮件地址转储一样。或者系统地从服务中删除他们的所有消息。该列表可以继续,但重点是,如果您决定使用自动增量字段作为主键,请确保使用该 ID 的所有页面都验证请求以确保 (a) 用户具有足够的权限,并且 (b) 请求未被伪造,可能是通过包含跨站点请求伪造令牌的方式,本质上是验证请求合法的 nonce 值。
泄露 URL 中的信息
即使一个不应访问它所指向的实际页面的人也可能可以访问一个 URL。毕竟,所有 URL 都可以显示在整个网络的链接中,或者通过引用标头泄漏。因此,URL 中不应包含敏感信息。
Mongo ID 包含有关对象创建时间的信息(从第一部分开始)。计数器仅包含有关创建对象的顺序的信息。
计数器还提供有关总共有多少物体的信息(参见德国坦克问题)。但是 Mongo ID 也是如此,因为最后一部分是全局计数器。它从一个随机数开始,因此它传达的信息较少,但是拥有大量 URL 的攻击者仍然可以估计文档的总数。
枚举攻击
如果 URL 是连续的,攻击者很容易获得所有资源的列表。这称为枚举攻击。
对于柜台来说,这显然很容易做到。对于 Mongo ID,这更难,因为您必须猜测创建了哪些毫秒对象。如果您对创建对象的时间有一个模糊的概念,您仍然可以暴力破解它。
结论
如果您担心在 URL 中泄露有关您的文档的信息或让用户枚举所有文档,那么这两种方法都非常糟糕。如果不是,这两种方法都可以。
第三种解决方案
如果上述问题让您担心,您可以使用随机 ID。使用大空间来减少碰撞的可能性,并进行一些错误处理,这样如果你不走运,事情就不会中断。
ID 可以存储为_id
(您可以覆盖默认值),也可以存储在名为url_id
或类似的字段中。在其上放置一个唯一的哈希索引以加快查找速度。
这会暴露 MongoDB ID 中的元信息,如jimbob 博士的回答中所述,这在某些方面是一个安全问题。
发布此问题的另一种方法是
在链接和 URI 中不公开有关我的数据库中条目的元信息的最佳做法是什么?
这个问题的答案很简单:对不与任何元信息绑定的条目使用唯一标识符字段。这些可以很容易地生成,与其他条目进行检查,如果发现冲突,则生成另一个。然后,您可以将其存储在 MongoDB 用于更快地查找这些文档的哈希/索引/任何系统中。
但是,这并不能解决人们通过社交媒体分享它们的问题,因此请确保您的安全模型考虑到这一点,并防止人们看到他们不应该看到的东西。