【问题标题】:How to hide a database ID from HTML/Javascript如何从 HTML/Javascript 中隐藏数据库 ID
【发布时间】:2011-11-02 10:38:16
【问题描述】:

如果我必须返回一个ID 比如说作为自动生成的主键 (Int64) 的消息,“隐藏”这个真实 ID 的最佳方法是什么?

当然,对于大多数事情,我可以理解它并没有太大的区别,但是我正在开发的应用程序意味着如果用户“猜测” URL 中的 ID 以拉回另一条记录,它可以证明是一个安全问题..

似乎有很多关于方法的想法/评论,但没有什么能引起人们的注意。

我想有一个自动生成的主 INT,但也有一个辅助的备用 GUID。它将是返回给任何前端进程的 GUID,当然自动生成的主 ID 仍将在后端使用..

当然的想法是 GUID 会更难猜测/获取另一个访问记录?

人们使用的任何想法或最佳实践?

提前致谢, 大卫。

【问题讨论】:

  • 我猜这个问题与stackoverflow.com/questions/1500087/… 类似,但我还是想听听其他选项?
  • 您始终可以在传递它之前对其进行加密...... GUID 也非常安全......加密的 GUID 可能是最安全的(极端但安全)

标签: c# javascript .net security url


【解决方案1】:

关于安全性,您有几个方面:

  • 会话劫持
  • 访问/修改/创建/删除用户无权访问/修改/创建/删除记录
  • 未经身份验证的访问
  • 跨站点*攻击
  • 中间人攻击

处理这些问题的措施取决于您的架构和安全需求。

由于您对您的架构和安全需求没有多说,因此很难给出任何具体建议...

关于“ID 不可猜测”的几点:

  • “正确”解决方案
    在您正确实施身份验证+授权的那一刻,问题就消失了 因为正确实施这两个确保只有经过身份验证的用户才能访问 任何东西,并且每个用户只能访问他被允许访问的东西。即使经过身份验证的用户知道他不被允许访问的东西的正确 ID,这也是安全的,因为他会阻止访问它。

  • “弱解”
    创建一个 ConcurrentDictionary 作为线程安全的内存缓存,并将真实 ID 和“临时 ID”(例如在第一次记录访问时新生成的 GUID)放在那里。您可以将该临时 ID 与某些特定连接方面(如客户端 IP、时间等)的盐和/或加密和/或哈希结合起来。然后在每次访问时检查 ConcurrentDictionary 并采取相应措施......一个积极的影响:在应用程序重新启动后(例如应用程序池回收),相同的记录会获得不同的 ID,因为这只是一个内存缓存......虽然这在网络农业场景中几乎不可用

【讨论】:

  • 嗨@Yahia 感谢您的意见。绝对正确,我应该对架构进行更多解释。基本上所有用户都必须登录,是的,他们只能看到他们被允许访问的内容(即他们可能拥有某个公司的用户 ID 等)。这意味着不让同一家公司的某些用户纯粹通过“猜测”该项目的 ID 来查看其他记录。正确地说,可能只是矫枉过正,每次执行后端进程时都会检查当前用户的凭据。只是试图减少对 ID 可见的感知。
  • 不客气 - 如果您所描述的内容得到适当实施(身份验证 + 授权),那么您为什么觉得“猜测 ID”可能是个问题?
  • 嗨,我再次认为这更多的是关于感知..这个应用程序是为时装设计师设计的,他们非常偏执。所以更多关于 url/id “看起来”安全的事实 - 因为正确的是,我们有一个登录名,并且该登录名只能访问他们打算访问的数据等。回头看,我应该重新表述这个问题并提供所有重要的上下文...
  • 然后实现 ConcurrentDictionary 方法——它是线程安全的并且非常快,因为大多数操作都是无锁实现的
  • 非常酷 - 我不知道那个类(ConcurrentDictionary)!
【解决方案2】:

我正在研究的方法是,如果用户“猜测” URL 中的 ID 以拉回另一条记录,这可能会证明是一个安全问题。”

如果是这种情况,那么您确实需要退后一步,重新审视安全方法。如果用户可以访问他们无权查看的记录,则您没有为您的对象引用提供适当的安全性 - https://www.owasp.org/index.php/Top_10_2010-A4-Insecure_Direct_Object_References

GUID 方法将尝试通过默默无闻的方式提供安全性,请参阅 Is using a GUID security though obscurity?,您必须根据自己的情况自行决定。

【讨论】:

  • 谢谢,是的,请参阅我的 cmets 到第一个答案.. 显然我应该多解释一点上下文.. 也感谢链接!
【解决方案3】:

当然,从技术上讲,通过查询另一个 ID 来拉回另一个记录是一件坏事——只有当另一个 ID 不应该对拉回它的用户可见时。但是无论如何你都会遇到安全问题,你应该专注于这个问题,而不是找到一种方法来混淆 ID

无论如何,如果您想弄乱网址,我建议您查看 Rijndael。我们在这里经常使用它来传递令牌。基本上,这种加密技术允许您加密和解密。因此,您可以加密 ID,将其发送给客户端,客户端将其发回,然后您可以简单地再次解密。不需要额外的数据库记录。更安全的是为当前客户端加密/解密使用 IP 之类的东西加盐的记录 ID,因此即使是 URL 钓鱼也将减少问题。

见:http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndael.aspx

【讨论】:

  • Obfuscate 的意思是“渲染模糊、不清楚或难以理解”。 OP 不是在谈论混淆,而是在使用真正的秘密(毕竟,大多数密码学和身份验证不是在某种程度上基于秘密吗?)
  • 如果某些东西是晦涩的、不清楚的或难以理解的,它在某种程度上不安全吗?算是一个很弱的水平吧。 en.wikipedia.org/wiki/Security_through_obscurity
  • 实际上,我必须再次道歉,因为我没有将我的查询放在上下文中(请参阅我对上面第一个答案的评论)..所以我确实有安全感(显然越来越多地学习如何让它变得更好当然).. 所以它实际上是关于隐藏 ID,而且因为该应用程序在安全性方面存在感知压力(对于时尚行业,因此设计图像等相当受保护等),该应用程序需要任何额外的安全性,甚至感知到的......所以感谢cmets,我会检查那个链接!!!
【解决方案4】:

我想说的是,URL 是公开的,它不是机密数据。无需对用户隐藏 url。如果一个 url 可以被一个用户看到并且不应该被另一个用户访问,你应该从服务器端检查用户的权限而不是隐藏那个 url。

【讨论】:

    【解决方案5】:

    所有其他答案 (3) 均未能涵盖这是非 cookie、非身份验证、非会话、非登录用户的可能性。

    比如下单后的确认页面等……

    在这种情况下,您的身份验证基于 URL 中的秘密。您使用的秘密对于所有实际目的都是不可猜测的,并且每条记录都非常独特。然后你假设如果用户有那个秘密,那么他们就可以访问所说的记录,等等......

    真正的挑战是找到一种制作秘密 UUID 的好方法。许多开发人员会采用 rand() + time() + uuid() + remote_ip() 的 SHA1() 或类似的东西(这通常就足够了),但我确信有很多关于这方面的文档。

    是的,在您有未经身份验证的用户访问特定数据或执行操作(例如密码重置)的情况下,您需要在您的记录中使用第二个标识符(例如 varchar 40)一个唯一的键(如您所概述的)。用非常随机的数据填充它,如果他们有那个秘密,那就让他们进来。

    保重。

    【讨论】:

    • 感谢您的评论!再次,请参阅我对上面回答 1 的评论。我真的应该提供更多详细信息/上下文。但可以肯定的是,无论如何我仍然希望隐藏 ID,甚至提供额外级别的“感知”安全性(假设应用程序必须登录,并且用户是 companyID 等的一部分)。
    猜你喜欢
    • 2020-02-24
    • 2012-08-17
    • 2015-04-12
    • 2021-04-12
    • 1970-01-01
    • 2012-08-15
    • 2017-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多