代码之家  ›  专栏  ›  技术社区  ›  Darryl Hein IrishChieftain

我应该模糊我的用户的数据库ID吗?

  •  30
  • Darryl Hein IrishChieftain  · 技术社区  · 16 年前

    有人告诉我,我不应该在Web应用程序的HTML代码中直接使用数据库ID。

    目前,我在诸如表行ID(TableRow-454,其中454是数据库中的行ID)、隐藏字段或选择表单或URL中的字段上使用这些ID。(我不是指在页面上用视觉告诉人们他们是。)

    我得到的建议是使用一些数学方法来模糊用户的ID。我认为这只会使事情变得更复杂,增加不必要的复杂性。但我可以看到一些很好的理由,使从HTML确定数据库ID变得更加困难。

    您是否混淆了用户的ID?还是你在乎?

    12 回复  |  直到 16 年前
        1
  •  42
  •   Greg    16 年前

    不,你只是在为自己做额外的工作。

    只要你做了足够的测试,在这里或那里更改一个ID不会给用户访问他们不应该访问的东西,那么你就可以看到这些ID。

    在某些情况下,隐藏它们或者使用非序列号,或者不从零开始计数可能是有益的。例如,如果有人收到订单3,他们可能会开始问问题…

        2
  •  11
  •   Erich Kitzmueller    16 年前

    伊莫:不,你不应该混淆身份证。如果您的应用程序担心安全问题,那么您无论如何都需要其他安全措施。默默无闻的安全是不够的,它只是给你一种虚假的安全感。

    顺便说一句,如果你只做一点数学运算,很有可能其他ID(也被模糊了)仍然是可预测的。在许多情况下,坏人不在乎他闯入了哪个账户,只要不是他自己的账户;—)

        3
  •  7
  •   Alexander Torstling    16 年前

    我想说一般来说没问题,但有一些问题:

    • 如果你的数字是连续的,你会打开“猜谜游戏”(例如,用户更改细节?ID=4511详情?ID=4512查看其他人的详细信息)。为了抵消这一点,你首先需要适当的保障。但在某些情况下,这还不够,因为透露信息的存在本身可能是一个问题。以youtube为例,他们使用更多的扩展ID:S来避免机器人屏幕的碎片。

    • 如果对id:s的性质进行假设,可能会遇到麻烦(即,如果直接在GUI中操作id:s或根据id对项目进行排序)。一旦你需要负载平衡你的数据库,最终得到独立的ID范围,这可能是一个令人讨厌的惊喜。

    • ID重用。例如,mysql:s innodb engine在重启时重置序列(到最新的max值)。如果你删除,这会让你很痛苦。

    但所有这些gotchas也适用于自定义ID:S,但可能是这些人的来源。在我看来,最灵活的解决方案是guid:s,因为您可以在任何地方生成它们,并且不会遇到上述任何问题。不过,它们很难为人类阅读,所以这是一种权衡。

        4
  •  6
  •   Dean J    16 年前

    是的,你可能应该。

    如果用户恶意更改这些ID,您的代码是否检查以确保他们请求的数据仍然是允许他们查看的数据?

    隐藏ID比在整个地方手动进行验证更容易。

    编辑,这次要清晰:

    如果您在屏幕上显示一个ID为1到20的列表,那么很容易验证响应是否在1到20之间。如果将实际ID显示到屏幕上,则需要花费内存缓存ID,或者需要进行另一个数据库调用/更长的查询,以确保它们不会给您提供坏数据。

    如果你使用代理ID,我想这会变得更容易。

        5
  •  4
  •   user166390    16 年前

    应该对用户隐藏数据库ID

    为什么?这是一个他们(用户)不需要关心的实现细节。我是123311122号身份证?谁在乎!(除非,也许我在ICQ上)。例如,看看如何将暴露最小化(但不能消除)。

    另一方面,使用可预测的ID也是另一种攻击手段,即隐蔽性的安全性,但它仍然是另一种有效的工具。我从来没有在软件上工作过,尽管这一直是个问题。

    也就是说,如果框架不提供处理“隐藏ID”或提供干净映射的方法,那么可能根本不值得切换。

        6
  •  3
  •   pbz    16 年前

    我会说,如果这个ID对用户有任何意义,并且您正在处理一个数据敏感的应用程序,那么您应该隐藏ID的值。更重要的是,我建议您验证当前用户是否有权访问他们通过URL请求的数据。例如,如果您有一个类似mysite.com/account/view/12的URL,当前用户是否有权访问该帐户ID(即12)。

    如果信息是公开的且不敏感,我会说不需要隐藏ID值。

        7
  •  2
  •   Keith Adler    16 年前

    我不想向用户公开任何与数据内部有关的内容,但是通常情况下都会发生这种情况,特别是在基于数据源创建下拉列表时。我的解决方案是在表上使用不同的标识规范,以消除增量攻击,并在可能的情况下加密querystring值。考虑到.NET中非常流行的MVC URL模式,这并不总是可能的,所以我倾向于使用一个唯一的列名,然后将其规范化为URL。然后我在数据库中查找该值。然而,要完全解决这个问题,没有一个简单的方法。

        8
  •  2
  •   Darryl Hein IrishChieftain    16 年前

    “有人告诉我,我不应该在Web应用程序的HTML代码中直接使用数据库ID。 … 是否混淆了用户的ID?“

    用户希望面对的数据能够与他们在工作中所处理的现实世界联系起来。

    “数据库ID”应该是用户界面的一部分,前提是这些ID也是用户实际工作环境的一部分。如果不是,那么应用程序确实应该完全保护用户不受此类字段的影响。

    做这种屏蔽确实意味着“更多的工作”,但这是完全无关的。不做这种屏蔽意味着给用户一个应用程序,这将使他更难处理,这最终将导致“更多的工作”由用户自己完成,每天一次又一次。

        9
  •  1
  •   Venemo    16 年前

    我建议你用友好的名字。它更现代,更语义化。此外,当您创建链接时,它看起来更好。

    例如,考虑mysite/products.aspx?ID=25 vs mysite/产品/法拉利。后者更干净,更容易记忆(对于用户),等等。

    如果当前正在隐藏字段中使用ID,请尝试使用会话存储这些值。如果只在您提到的表行ID中使用它们,我认为不值得花时间隐藏它们。

        10
  •  1
  •   Community Mohan Dere    9 年前

    ID:s in URI:s are a part of a good UI 如果你希望你的用户能够走那条路。无论如何,所有的uri:s都是公共的,由响应页面来处理请求,并基于某种身份验证进行呈现。

    事务和其他敏感材料可以很容易地用一个salted+hashed字符串隐藏并存储在数据库的另一列中(如果您愿意),但如果您仍然没有 正在验证用户输入 (在Web编程中很明显,这可能是“通过URI导航”)您错过了要点。

    AS Greg answered ,订单号可能不应太低,但 这种信息处理的责任不应在网页内,而应在组织的/你的规定价值范围内。 (也就是说,你仍然会在书面收据上打印出订单号,所以为什么要先隐藏它?)

    由于网络和今天一样透明,除了它过去的使用方式外,很难找到其他的用途。 缩短URI: S 例如YouTube的视频页面和无数的URI缩短服务。

        11
  •  1
  •   Community Mohan Dere    9 年前

    作为向公众“发布”ID的示例,请查看此文章的URL。

    我试过 https://stackoverflow.com/questions/1 ,但它似乎已被删除。你得去 While applying opacity to a form should we use a decimal or double value? 找到“第一个”序数问题;)

    …没有伤害,只是参考了另一篇文章。

        12
  •  1
  •   BillB    16 年前

    如果您确实决定在隐藏字段中篡改不可篡改的行ID,您可以查看Steve Sanderson在第415页上的ASP.NET MVC书籍,他为此提供了一个HMAC(哈希消息验证代码)实用程序类。当然是.NET,但你可以理解。你可以在谷歌图书上看到它(Sanderson写了我读过的最好的编程书)。

    当我在HTML中输入行ID,并且业务模型说用户应该可以访问某组行(例如他/她插入的行)时,我可能会设计一个DB表来包含一个用户ID列,并将其包含在任何DB操作中(伪代码:其中@row id=table.row id和@user id=table.user id)。这样,如果另一个用户在隐藏字段中入侵rowid,那么db操作不会让他们看到另一个用户的数据,因为该用户的ID不匹配。当然,这种方法假定您正在使用某种类型的身份验证,而且它也没有被黑客攻击。

    推荐文章