26

我经常遇到通过选择框等表单公开内部数据库主键的 Web 应用程序。有时我会看到 javascript 与切换逻辑的 int 或 guid 魔术值匹配。

这是避免泄露 Web 应用程序中行的所有内部标识符的最佳实践,以防止外人过多地了解您的系统并可能使用它来利用您的系统。如果是这样,解决此问题的最佳方法是什么?

您是否应该向 Web 应用程序公开一些可以转换回主键的其他值?

谢谢

编辑

在一个完美的世界里,你的应用程序将是 100% 安全的,所以如果你把事情弄得模糊不清也没关系。显然情况并非如此,所以我们是否应该谨慎行事而不公开这些信息?

有人指出 Stackoverflow 可能会在 Url 中公开一个键,这可能很好。但是,企业应用程序的考虑因素是否不同?

4

6 回答 6

33

我不同意公开主键是一个问题的立场。如果你让它们对用户可见,这可能是一个问题,因为它们在系统之外被赋予了意义,这通常是你试图避免的。

但是使用 ID 作为组合框列表项的值?去吧,我说。与某个中间值进行转换有什么意义?您可能没有要使用的唯一密钥。这样的翻译引入了更多潜在的错误。

只是不要忽视安全。

如果说你向用户展示了 6 个项目(ID 1 到 6),永远不要假设你只会从用户那里得到这些值。有人可能会尝试通过发回 ID 7 来破坏安全性,因此您仍然必须验证您返回的内容是否被允许。

但完全避免这种情况?没门。没必要。

正如对另一个答案的评论所说,请查看此处的 URL。这包括毫无疑问是 SO 数据库中问题的主键。将密钥公开用于技术用途是完全可以的。

此外,如果您确实使用了一些代理值,那不一定更安全。

于 2009-04-30T13:13:16.640 回答
3

是的,你所有的问题。我同意您的主张,即您应该“向 Web 应用程序公开一些其他可以转换回主键的值

否则,您可以向潜在的问题敞开心扉。

编辑

关于“没有理由为微不足道的键受到惩罚。现在查看浏览器的 URL,我敢打赌你会看到一个键! ”的评论。

我明白你在说什么,是的,我确实在 SO URL 中看到了密钥,并同意它可能确实引用了数据库 PK。我承认在这样的情况下,如果没有更好的选择可能没关系。

我仍然更愿意公开 PK 以外的东西——具有语义价值的东西。问题的标题也在 URL 中,但由于这很难验证是唯一的(或在用户之间口头传递),它不能单独可靠地使用。

然而,当查看“标签”URL(即https://stackoverflow.com/questions/tagged/java+j2ee)时,不会公开 PK,而是使用标签名称。就个人而言,我更喜欢这种方法,并会为此而努力。

我还想补充一点,PK 指向的数据有时会随时间而变化。我在一个系统上工作过,其中一个表填充了来自离线进程的信息 - 即每月统计数据,其中数据库表内容在月底下降并重新填充了新数据。

如果数据以不同的顺序添加到数据库中,特定数据点的 PK 将发生变化,并且从上个月保存到该数据的任何书签现在将指向不同的数据集。

这是公开 PK 会“破坏”与应用程序安全性无关的应用程序的一个实例。生成的密钥并非如此。

于 2009-04-30T13:07:37.560 回答
3

是的,暴露密钥是可以用作攻击的信息。特别是如果它们是可预测的。

如果您认为信息很敏感,请使用不同的键/列。

例如,为了避免显示您拥有的用户数量,请考虑:

site.com/user/123 与 site.com/user/username

于 2009-04-30T13:08:05.670 回答
0

一如既往,“这取决于”。如果某人可以通过知道您每(小时/天/月)执行多少交易来获得价值(例如),并且您将交易 ID 公开为单调递增的数字,那么这是一种风险。

正如其他人所说,对于值的下拉列表,通常没有问题。

于 2009-04-30T13:38:51.433 回答
0

公开除主键之外的其他值不会避免您检查安全性的负担。事实上,如果您的安全存在漏洞,“邪恶”用户可能仍会通过更改 url 中的值来访问他们不打算访问的对象。他们可能对使用哪些值没有多少线索,但随机选择值,他们可能会很幸运。

如果您想以这种方式提高安全性,您将不得不在 url 中使用大随机字符串(以使猜测变得困难),而不是 id,并在后台使用将随机值与好的 id 匹配的间接表。

我认为大多数时候不值得麻烦。

也就是说,这对于您想要“隐蔽安全”的情况很有用,例如当您公开更改用户密码的页面时,不需要登录(对于丢失密码的用户)。在这种情况下,您还应该将限制有效日期与您的密钥相关联。

于 2009-04-30T13:55:17.353 回答
0

主键与代理键或内部键不同,尽管有一些重叠。与内部密钥相反的是自然密钥。很多时候自然键被用作主键。一般来说,没有理由隐藏自然密钥,除非我们正在处理隐私问题。

我认为,您真正的问题是是否应该向用户公开内部密钥。答案是“视情况而定”。对于大多数用户社区,公开内部密钥将导致该密钥被用作自然密钥。当内部键和表行的主题之间的一对一映射发生故障时,这可能并且通常会导致一些混乱。

这种故障只会由于数据管理不善而发生。然而,大多数时候,您必须对现实世界中发生的一些数据管理不善进行计划。你不会计划一个供水系统,只要有水管理不善就会崩溃。您不会计划一个每次出现数据管理不善时都会崩溃的信息系统。

话虽如此,如今大多数数据库设计人员都在为软件供应商工作,并没有看到他们产品的用户因数据管理不善而导致的问题。

于 2009-05-02T11:35:11.133 回答