【问题标题】:Avoid exposing primary keys in the source of a web app?避免在 Web 应用程序的源代码中暴露主键?
【发布时间】:2010-10-22 20:23:42
【问题描述】:

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

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

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

谢谢

编辑

在一个完美的世界中,您的应用程序将是 100% 安全的,因此即使您隐藏了某些东西也没关系。显然情况并非如此,所以我们是否应该谨慎起见而不公开这些信息?

有人指出 Stackoverflow 可能会在 Url 中公开一个键,这可能没问题。但是,企业应用程序的注意事项是否有所不同?

【问题讨论】:

    标签: security database-design architecture web-applications data-modeling


    【解决方案1】:

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

    否则你可以敞开心扉面对潜在的问题。

    编辑

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

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

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

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

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

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

    在这种情况下,公开 PK 会“破坏”与应用安全无关的应用。生成的密钥则不然。

    【讨论】:

    • 这不是绝对的,也没有理由为琐碎的钥匙而受到惩罚。立即查看浏览器的 URL,我敢打赌你会看到一个键!
    • 我没有看到您显示任何安全流程或为什么您更喜欢代理密钥。此外,您给出的示例只是糟糕的设计。
    【解决方案2】:

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

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

    例如,为了避免显示您拥有多少用户,请考虑:

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

    【讨论】:

      【解决方案3】:

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

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

      只是不要忽视安全。

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

      但是完全避免这种情况?没门。不需要。

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

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

      【讨论】:

      • +1 我同意。使用一些任意值来避免显示某物的 ID 充其量是通过混淆实现安全性(阅读:不太好)。您的安全性应该足够强大,可以拒绝用户伪造值。
      • 但是...从数据库中获得的 PK 代表表中将用于生成网格的行呢?
      • @nickf 您是否考虑将密码存储为哈希而不是纯文本作为security-through-obfuscation
      • @buffer 不,我不会。
      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

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

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

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

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

        【讨论】:

          【解决方案6】:

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

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-07-05
            • 2016-08-07
            • 1970-01-01
            • 2018-08-04
            • 1970-01-01
            • 1970-01-01
            • 2021-10-11
            • 1970-01-01
            相关资源
            最近更新 更多