暴露数据库ID-安全风险?


133

我听说公开数据库ID(例如,在URL中)存在安全风险,但是我很难理解原因。

是否对为什么有风险有任何意见或链接?

编辑:当然,访问范围是有限的,例如,如果您看不到资源foo?id=123,则会看到错误页面。否则,URL本身应该是秘密的。

编辑:如果URL是机密的,则它可能包含一个生成的令牌,该令牌的寿命有限,例如,有效期为1小时,只能使用一次。

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

Answers:


108

在适当的条件下,公开标识符不是安全风险。而且,实际上,在不公开标识符的情况下设计Web应用程序将非常繁重。

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

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

27
国际海事组织(IMO)添加不可预测的ID是一种“通过模糊实现安全”的方法,并且可能导致错误的安全感。最好专注于(1)和(2)并确保您的访问控制是可靠的。
stucampbell 2014年

4
使用加密的RNG绝对不是“默默无闻的安全性”。攻击者即使知道对象标识符的生成方式,也无法猜测对象标识符。默默无闻的安全性意味着,如果发现您正在使用的算法,则可以利用该算法。它不是指保守秘密,例如密钥或RNG的内部状态。
erickson

1
@stucampbell也许,但这并不意味着您根本不应该使用不可预测的ID。会发生错误,因此不可预测的ID是一种额外的安全机制。此外,访问控制不是使用它们的唯一原因:可预测的ID可以揭示敏感信息,例如在特定时间范围内的新客户数量。您确实不想公开这些信息。
user247702 '18

1
@Stijn,您不能真的说我“真的不想”透露我有多少客户。我的意思是麦当劳有一个很大的信号说他们已经为100亿个汉堡包服务。这根本不是安全隐患,而是首选。此外,您必须先登录,然后才能在大多数应用程序中看到任何仍然要为此担心的URL。因此,我们将知道谁在抓取数据。
韦恩·布鲁斯

1
在此对话中我没有看到的一件事是,从故障排除和易用性的角度来看,将ID公开在URL中以帮助将用户定向到特定资源或使他们能够告诉您他们正在查看哪些资源。您可以通过以更高的值启动自动增量来避免商业智能方面的顾虑,只是提供一个想法。
Chockomonkey

47

尽管不是数据安全风险,但这绝对是商业智能安全风险,因为它同时暴露了数据大小和速度。我已经看到企业受到了这种伤害,并且已经深入地介绍了这种反模式。除非您只是在做实验而不是做生意,否则我强烈建议您不要公开您的私人身份证。https://medium.com/lightrail/prevent-business-intelligence-leaks-by-using-uuids-instead-of-database-ids-on-urls-and-in-apis-17f15669fd2e


4
最后,理智的答案带来了除安全风险以外的其他方面。
peceps

2
这应该是公认的答案。如果您假设攻击者可以绕过您的安全性(您应该始终这样做),那么您就不会只想传递此类信息。
克里尔

@Kriil他们甚至不需要绕过您的安全性。他们只需要创建一个帐户!
Peter

32

这取决于ID代表什么。

考虑一个出于竞争原因不想公开其拥有多少成员但通过使用顺序ID仍在URL中显示该站点的站点:http : //some.domain.name/user? id= 3933

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


2
如果您使用的是顺序ID,那么您是对的,但是如果没有,则不会显示任何内容
orip

@orip:就像我说的,这取决于某人通过检查多个ID可以发现什么。有模式吗?他们可以使用这些信息来获取他们不想要的信息吗?
一些

@John:感谢您的编辑。英语不是我的母语:)
大约

6
我正是这样做的:使用顺序ID号来确定竞争对手的用户群的大小。
米卡

3
他们无处不在。许多购物网站使用顺序号作为订单ID。在一个日期下一个订单,在另一个日期下一个订单,您知道他们在此期间收到了多少订单。即使您不知道这些订单的价值多少,您也仍然可以了解到业务进展情况。
一些

25

普遍的思路是:“向任何人公开有关您应用内部运作的信息。”

公开数据库ID被视为公开了一些信息。

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


1
访问他们不应该看到的资源-仅在不检查权限的情况下(我这样做,否则会遇到其他安全问题)。公开有关“内部工作原理”的信息-这正是我的问题。为什么会出问题呢?
orip

8
@orip:尽可能地确保安全。如果您是那种不会犯错误的程序员,那么这不是问题。否则,如果您犯了错误,则暴露较少的细节将使利用代码变得更加困难。就其本身而言,您是对的,它不会增加安全性。
亚当·贝莱尔

@亚当:表面上的安全总比没有安全要糟。如果没有安全性,那么您将是明确的;如果具有表面安全性,您可能会认为它增加了一些不可忽视的内容。
orip

16

我们使用GUID作为数据库ID。泄漏它们的危险要小得多。


这就是我的建议。猜测数据库中的GUID的可能性大大降低。
乔恩·埃里克森

6
这会降低性能。看到这里
Jeshurun

2
关于使用guids的有趣的事情1是,您可以让客户端生成数据库ID。有趣的事情2是,它们对分片数据库没有问题,就像自动递增id一样。
布赖恩·怀特

您是否还在html代码中使用这些GUID作为id属性来标识用户,评论和帖子?要表明用户单击了哪个链接或他要评论哪个帖子?
trzczy

7

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

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


7
如果我不检查权限,则会遇到其他安全问题。
orip

但答案是正确的:“可能”
Seun Osewa

1
问题不是您是否要检查权限。如果您不认识的新员工将检查权限。
Brian White

@BrianWhite-这就是为什么需要适当的代码审查过程,以便可以在产品投入生产之前进行培训。
candu 2015年

2
我们要做的是在URL或表单变量中使用时对整数ID进行加密。
布赖恩·怀特

6

当您发送数据库ID对你的客户,你都不得不在这两种情况下,检查安全性。如果将ID保留在您的Web会话中,则可以选择是否要/需要这样做,这意味着处理可能更少。

您一直在尝试将事情委托给您的访问控制;)在您的应用程序中可能会出现这种情况,但是我从没在整个职业生涯中看到过如此一致的后端系统。他们中的大多数人都具有专为非Web使用而设计的安全模型,有些人死后又添加了其他角色,其中一些人被附加在核心安全模型之外(因为该角色是在不同的操作环境中添加的,例如,在网络之前)。

因此,我们使用合成会话本地ID,因为它隐藏了尽可能多的内容。

还存在非整数键字段的问题,枚举值和类似值可能会出现这种情况。您可以尝试对数据进行清理,但是最终您可能会像小小的鲍勃放置表那样


4
有趣的是,尽管我认为检查每个请求的所有输入(包括URL参数)非常适合Web。
Orip
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.