【问题标题】:UUID on database level used as a security measure instead of a true rights control?数据库级别的 UUID 用作安全措施而不是真正的权限控制?
【发布时间】:2016-07-03 16:35:17
【问题描述】:

数据库级别的 UUID 可以用作安全措施而不是真正的权限控制吗?

考虑一个 Web 应用程序,其中所有 servlet 通过将会话 ID 连接到调用它的用户(通过 Web 客户端)来实现“正常”访问控制。因此,所有用户都经过身份验证。

需要的下一个安全级别是经过身份验证的用户是否真正“拥有”正在更改的数据。例如,在 Web 应用程序中,这可能是在表单中编辑某些文本。客户端确保用户不会意外地做错事(JavaScript)。问题当然是任何数量的网络工具都可以轻松地重复浏览器进行的调用,并且仅通过更改 ID,在用户不“拥有”的 servlet 后面的数据库表中编辑不同的行。

我的问题是使用 UUID 作为数据库表中的键是否足够,从而实际上无法猜测有效 ID (https://en.wikipedia.org/wiki/Universally_unique_identifier#Random_UUID_probability_of_duplicates)?据我所知,Google 照片 (http://www.theverge.com/2015/6/23/8830977/google-photos-security-public-url-privacy-protected) 中使用了类似的方法,但我不确定它是否 100% 具有可比性。

另一个选项是让每个 servlet 验证用户只对自己的数据执行操作,但在一个有 200 多个 servlet 和 50-100 个表的大型应用程序中,这可能是一项非常繁琐的任务,可能会出现错误很容易发生。在我看来,这大大削弱了安全性,但我不确定这是否属实。

我倾向于 UUID 解决方案,但我也很好奇是否还有其他明显的方法可以解决这个问题。

更新:

我可能应该澄清我的计划是使用应该是随机的 UUIDv4。我知道熵在这里起到了关于 UUID 的实际随机性的作用,但据我所知,Java(这是选定的平台/语言)使用 SecureRandom,它应该是“加密强”(@ 987654323@)。

在这种情况下,wiki 状态 (link): 换句话说,仅在接下来的 100 年每秒生成 10 亿个 UUID 之后,仅创建一个副本的概率约为 50%。

【问题讨论】:

    标签: security servlets uuid


    【解决方案1】:

    以这种方式使用 UUID 有两个主要问题:

    1. 如果没有其他身份验证方法,任何攻击者都可以简单地猜测 UUID,直到找到属于其他人的 UUID。 Google 相册不需要过多担心这一点,因为它们只使用 UUID 来混淆公开共享的照片视图;您仍然需要进行身份验证才能修改照片。这尤其危险,因为:
    2. UUID 应为 unique, not random。您的 UUID 中可能存在攻击者能够观察和利用的可预测模式。此外,即使没有明确的模式,攻击者需要测试以找到有效 UUID 的数量也会随着用户群的增长而迅速减少。

    我将始终建议使用安全、持续检查的身份验证。但是,如果您有一个相当小的用户群,并且您只是使用它来混淆公共数据访问,那么以这种方式使用 UUID 可能没问题。即使那样,您也应该使用实际的随机字符串,而不是 UUID。

    【讨论】:

      【解决方案2】:

      另一个选项是关闭原因让每个 servlet 验证用户 仅对自己的数据执行操作,但在大型应用程序中 有 200 多个 servlet 和 50-100 个表,这可能非常麻烦 容易出错的任务。在我看来,这削弱了 安全性更高,但我不确定这是不是真的。

      对于大型遗留应用程序,以后添加安全性始终是一项复杂的任务。你是对的——应用程序越复杂,验证安全性就越困难。复杂性是安全的主要敌人。

      但是,这是最好的方法,而不是试图掩盖insecure direct object reference 的问题。

      如果您在查询字符串中使用这些 UUID,则 URL 中的这些信息可能会记录在不同的位置,包括用户的浏览器、Web 服务器以及两个端点之间的任何正向或反向代理服务器。 URL 也可以显示在屏幕上,由用户添加书签或通过电子邮件发送。当遵循任何场外链接时,它们可能会通过Referer 标头披露给第三方。将直接对象引用放入 URL 会增加它们被攻击者捕获的风险。应用程序的现有用户随后被撤销对某些数据位的访问 - 他们仍然能够通过使用以前添加书签的 URL(或使用他们的浏览器历史记录)访问这些数据。即使 ID 是在 URL 机制之外传递的,知道(或已经弄清楚)您的系统如何工作的本地攻击者也可能会故意保存 ID 以备不时之需。

      正如其他答案所说,GUIDs/UUIDs are not meant to be unguessable, they are just meant to be unique。诚然,Java 实现确实会生成加密安全的随机数。但是,如果此实现在未来版本中发生更改,或者如果您的系统移植到其他功能不同的地方怎么办?如果您要这样做,您不妨使用自己的实现生成自己的加密安全随机数以用作标识符。如果您的标识符中有 128 位熵,那么任何人都完全不可能猜到它们(即使它们拥有世界上所有的计算能力)。

      但是,出于上述原因,我建议您改为实施访问检查。

      【讨论】:

        【解决方案3】:

        您正试图绕过授权控制,希望密钥不可猜测。这是一个安全禁忌。根据您询问的对象,他们可能会将其称为insecure direct object reference 或违反complete mediation principle

        正如 F. Stephen Q 所指出的,您认为 UUID 是唯一的并不意味着它们是不可预测的。这里的威胁是,如果用户知道几个 UUID,比如说他自己的,这是否允许他预测其他人的 UUID?这是一个非常真实的威胁,请参阅:Cautionary note: UUIDs generally do not meet security requirements。特别注意 UUID RFC 所说的:

        不要假设 UUID 很难猜;它们不应该被用作 安全能力(仅仅拥有授权的标识符 访问),例如。

        您可以将 UUID 用于密钥,但仍需要进行授权检查。当用户想要访问他的数据时,数据库应该识别数据的所有者,并且服务器逻辑需要强制当前用户与数据库声称的所有者相同。

        【讨论】:

          猜你喜欢
          • 2011-11-01
          • 2015-01-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-15
          • 2011-12-15
          相关资源
          最近更新 更多