我应该从用户那里混淆数据库ID吗?

时间:2009-11-04 19:22:25

标签: database obfuscation

我被告知我不应该直接在Web应用程序的HTML代码中使用数据库ID。

目前我在表行ID(tableRow-454,其中454是数据库中行的ID),隐藏或选择表单或URL中的字段等事物上使用ID。 (我不是指在页面上直观地告诉人们他们是####。)

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

您是否对用户的ID进行了模糊处理?或者你在乎吗?

12 个答案:

答案 0 :(得分:42)

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

只要您进行了足够的测试,在此处更改ID或者不会让用户访问他们不应该访问的内容,那么您可以很好地查看ID。

在某些情况下隐藏它们或具有非连续数字或者可能不从零开始计数可能是有益的。例如,如果某人获得了第3号订单,他们可能会开始提问......

答案 1 :(得分:11)

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

顺便说一下,如果你做一点点数学运算,那么其他身份证明 - 也可能是模糊的 - 仍然是可以预测的。在许多情况下,坏人不关心他闯入哪个账户,只要不是他自己的账户; - )

答案 2 :(得分:7)

我会说它一般都可以,但有一些问题:

  • 如果您的号码是连续的,您可以打开“猜猜游戏”(例如,用户更改详细信息?id = 4511以获取详细信息?id = 4512以查看其他人的详细信息)。要抵消这一点,首先需要适当的安全性。在某些情况下,这是不够的,因为揭示信息存在本身可能是一个问题。以Youtube为例,他们使用更多的传播ID:s以避免机器人屏幕刮擦。

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

  • ID重用。例如,MySql:s InnoDB引擎在重启时重置序列(到最新的最大值)。如果删除,这会让你很难受。

但所有这些陷阱也适用于自定义ID:s,但可能是这些人来自的地方。我眼中最灵活的解决方案是GUID:s,因为您可以在任何地方生成它们,并且不会遇到任何上述问题。然而,它们对人类来说更难阅读,所以这是一种权衡。

答案 3 :(得分:6)

是的,你可能应该这样做。

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

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

编辑,这次是清晰的:

如果您在屏幕上显示ID为1到20的列表,则可以非常轻松地验证响应是否在1到20之间。如果您将实际ID显示到屏幕,则需要花费内存缓存ID,或者需要进行另一次数据库调用/更长时间的查询以确保它们不会向您提供错误数据。

如果您使用代理人ID,我认为这会变得更容易。

答案 4 :(得分:4)

您应该隐藏用户的数据库ID

为什么呢?这是一个实现细节,他们(用户)不需要关心。我是ID 123311122?谁在乎! (除非,也许我在ICQ上)。例如,了解SO如何最小化(但不消除)暴露。

在次要说明中,使用可预测的ID也是另一种攻击媒介,默默无闻的安全性,但它仍然是另一种有效的工具。我从未研究过这个问题的软件。

话虽如此,如果您的框架没有提供处理“隐藏ID”或以其他方式提供干净映射的方法,那么切换它可能根本不值得。

答案 5 :(得分:3)

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

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

答案 6 :(得分:2)

我不喜欢向用户公开任何谈论数据内部的内容,但是通常总是会发生这种情况,尤其是在创建基于数据源的下拉列表时。我的解决方案是在表上使用不同的标识规范来消除增量攻击,并在可能的情况下加密查询字符串值。鉴于.NET中非常流行的MVC URL模式,这并不总是可行的,因此我倾向于使用唯一的列名称,然后将其标准化为URL。然后我在数据库中查找该值。然而,没有简单的方法可以完全解决它。

答案 7 :(得分:2)

“我被告知我不应该直接在Web应用程序的HTML代码中使用数据库ID。 ... 你是否对用户的ID进行了模糊处理?“

用户希望面对的数据可以链接到他们在工作中处理的现实世界。

“数据库ID”应该只是用户界面的一部分,只要这些ID也是用户现实工作情况的一部分。如果不是,那么应用程序确实应该完全屏蔽用户这些字段。

这种屏蔽确实相当于“更多工作”,但这完全无关紧要。不进行这种屏蔽意味着给用户提供一个难以处理的应用程序,这最终会导致用户自己完成“更多工作”,每天都会重复。

答案 8 :(得分:1)

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

例如,考虑mysite / products.aspx?id = 25 vs mysite / products / ferrari。后者更清晰,更容易记住(对于用户),等等。

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

答案 9 :(得分:1)

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

如果您愿意,可以使用salted +散列字符串轻松隐藏事务和其他敏感材料,并将其存储在数据库的另一列中,但如果您仍未验证用户输入(在网络编程中显然可能是“在URI中导航”)你忽略了这一点。

作为Greg answered,订单号可能不会很低,但此类信息处理的责任不在于网页内,而在于组织内/您声明的值(即你仍然会在书面收据上打印出订单号,那么为什么要把它隐藏起来呢?)

由于网络像今天一样透明,除了用于缩短URI:s 的方式之外,很难找到它的另一种用途,即Youtube的视频页面和无数的URI缩短服务。

答案 10 :(得分:1)

作为向公众“发布”身份证的示例,请查看此帖子的网址。

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

......没有伤害,只是对另一篇文章的引用。

答案 11 :(得分:1)

如果您确定在隐藏字段中确定防篡改行ID,您可能会在第415页上查看Steve Sanderson的asp.net mvc书籍,其中为此目的提供了HMAC(哈希消息验证代码)实用程序类。它当然是.NET,但你可以得到这个想法。你可以在Google Books上看到它(Sanderson写过关于我读过的最好的编程书)。

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