公开数据库ID - 安全风险?

ori*_*rip 118 database security

我听说暴露数据库ID(例如在URL中)存在安全风险,但我无法理解原因.

关于为何存在风险或为何不存在风险的任何意见或联系?

编辑:当然访问是作用域的,例如,如果你看不到资源,foo?id=123你会得到一个错误页面.否则URL本身应该是秘密的.

编辑:如果URL是秘密的,它可能包含生成有限的生成令牌,例如有效1小时,只能使用一次.

编辑(几个月后):我目前的首选做法是使用UUIDS作为ID并公开它们.如果我使用序列号(通常用于某些DB上的性能)作为ID,我喜欢为每个条目生成一个UUID令牌作为备用键,并公开它.

eri*_*son 95

在适当的条件下,暴露标识符不是安全风险.并且,在实践中,设计Web应用程序而不暴露标识符将是非常繁重的.

以下是一些要遵循的好规则:

  1. 使用基于角色的安全性来控制对操作的访问.如何完成这取决于您选择的平台和框架,但许多支持声明性安全模型,当操作需要某些权限时,该模型将自动将浏览器重定向到身份验证步骤.
  2. 使用编程安全性来控制对对象的访问.这在框架层面上更难做到.更常见的是,您必须在代码中写入内容,因此更容易出错.此检查不仅基于角色检查,还通过确保用户具有操作权限,还具有对要修改的特定对象的必要权限.在基于角色的系统中,很容易检查只有经理可以加薪,但除此之外,您需要确保员工属于特定经理的部门.
  3. 对于大多数数据库记录,条件1和2就足够了.但添加不可预测的ID可以被认为是一个额外的保险,或"深度安全",如果你购买这个概念.但是,不可预测标识符是必需的一个地方是会话ID或其他身份验证令牌,其中ID本身对请求进行身份验证.这些应该由加密RNG生成.

  • IMO,添加不可预测的ID是一种"通过默默无闻的安全"方法,可能导致错误的安全感.最好关注(1)和(2)并确保您的访问控制是可靠的. (25认同)
  • 使用加密RNG绝对不是"通过默默无闻的安全性".即使知道如何生成对象标识符,攻击者也不会更接近猜测对象标识符.通过默默无闻的安全意味着如果您正在使用的算法被发现,它就可以被利用.它并不是指保密,如钥匙或RNG的内部状态. (2认同)
  • @stucampbell 也许吧,但这并不意味着您根本不应该使用不可预测的 ID。错误会发生,因此不可预测的 ID 是一种额外的安全机制。此外,访问控制并不是使用它们的唯一原因:可预测的 ID 可以揭示敏感信息,例如特定时间范围内的新客户数量。你真的不想暴露这些信息。 (2认同)
  • @Stijn,你不能真的说我“真的不想”暴露我有多少客户。我的意思是麦当劳有一个巨大的牌子,上面写着他们已经提供了 100 亿个汉堡。这根本不是安全风险,而是一种偏好。此外,在大多数应用程序中您必须先登录才能看到任何 URL,无论如何我们都会担心这一点。因此我们会知道谁在抓取数据。 (2认同)
  • 我在这次谈话中没有看到的一件事是,从故障排除和易用性的角度来看,在 url 中公开 ID 以帮助将用户定向到特定资源或让他们能够非常方便告诉你他们正在查看什么资源。您可以通过以更高的值启动自动增量来避免商业智能问题,只是为了提供一个想法。 (2认同)

som*_*ome 30

这取决于ID代表什么.

考虑一个网站,出于竞争原因,不希望公开他们拥有多少成员,但通过使用顺序ID,无论如何都会在URL中显示它:http://some.domain.name/user? id = 3933

另一方面,如果他们使用用户的登录名:http://some.domain.name/user?id = some,他们没有透露任何用户不知道的内容.

  • 我完成了这个:使用顺序ID号来确定竞争对手用户群的大小. (5认同)
  • 他们无处不在.许多购物中心使用序号来获取订单ID.在一个日期下一个订单,在另一个日期下一个订单,您知道在此期间他们获得了多少订单.即使您不知道订单价值多少钱,您仍然可以了解业务的进展情况. (3认同)
  • 如果您正在使用顺序ID,那么您是对的,但如果没有,则不会暴露任何内容 (2认同)

Pet*_*ter 26

虽然不是数据安全风险,但这绝对是商业智能安全风险,因为它暴露了数据大小和速度.我已经看到企业因此而受到伤害,并且已经深入了解了这种反模式.除非你只是在建立一个实验而不是一个企业,否则我强烈建议让你的私人信息不受公众的注意.https://medium.com/lightrail/prevent-business-intelligence-leaks-by-using-uuids-instead-of-database-ids-on-urls-and-in-apis-17f15669fd2e

  • 最后,理智的答案带来了安全风险之外的其他方面。 (10认同)
  • 这应该是公认的答案。如果您认为攻击者可以绕过您的安全措施(您应该始终这样做),那么您不想只交出此类信息。 (2认同)
  • @Kriil 他们甚至不需要绕过你的安全措施。他们只需要创建一个帐户! (2认同)

Arj*_*nbu 22

一般的想法是这样的:"向任何人公开关于你的应用程序内部工作的信息."

公开数据库ID计为披露某些信息.

这样做的原因是,黑客可以使用有关您的应用程序内部工作的任何信息来攻击您,或者用户可以更改URL以进入他/她不希望看到的数据库?

  • @orip:尽可能保证安全.如果你是那种不犯错误的程序员,那么这不是问题.否则,暴露较少的细节会使你在错误时(如果)犯错时更难以利用你的代码.就其本身而言,它是对的,它不会增加安全性. (5认同)
  • 访问他们不应该看到的资源 - 仅当我不检查权限时(我会这样做,否则我会遇到不同的安全问题)。披露有关“内部运作”的信息 - 这正是我的问题。为什么这是一个问题? (2认同)

Jos*_*hua 14

我们对数据库ID使用GUID.泄漏它们的危险性要小得多.

  • 这会带来性能损失.见[here](http://kccoder.com/mysql/uuid-vs-int-insert-performance/) (6认同)
  • 使用 guid 的有趣之处 1 是您可以让客户端生成数据库 id。有趣的事情 2 是他们对分片数据库没有问题,就像自动递增 id 那样。 (2认同)

Jas*_*son 7

如果在数据库中使用整数ID,则可以通过更改qs变量使用户轻松查看不应该存在的数据.

例如,用户可以轻松更改此qs中的id参数,并查看/修改数据,他们不应该http:// someurl?id = 1

  • 如果我不检查权限,我有一个不同的安全问题. (6认同)
  • @BrianWhite - 这就是为什么您需要适当的代码审查流程,以便您可以在投入生产之前对他们进行教育。 (3认同)
  • 我们要做的是在URL或表单变量中使用整数ID时进行加密。 (2认同)

kro*_*old 6

当您向客户端发送数据库ID时,您将被迫在两种情况下检查安全性.如果您将ID保留在Web会话中,您可以选择是否需要/需要执行此操作,这意味着可能会减少处理.

您一直在尝试将内容委托给您的访问控制;)在您的应用程序中可能就是这种情况,但我在整个职业生涯中从未见过如此一致的后端系统.他们中的大多数都拥有专为非网络使用而设计的安全模型,其中一些在死后添加了其他角色,其中一些已经在核心安全模型之外进行了固定(因为该角色是在不同的运营环境中添加的,比如说在网络之前).

所以我们使用合成会话本地id,因为它隐藏了尽可能多的东西.

还存在非整数关键字段的问题,对于枚举值和类似情况可能是这种情况.您可以尝试对这些数据进行清理,但很可能最终会像小小的丢弃表一样.

  • 有趣的是,虽然我认为检查每个请求的所有输入(包括URL参数)非常适合Web. (4认同)