我应该在应用程序前端隐藏数据库主键 (ID) 吗?

信息安全 php mysql
2021-08-12 10:58:00

我正在开发一个允许版主编辑用户信息的应用程序。所以,目前,我有类似的 URL

http://www.example.com/user/1/edit
http://www.example.com/user/2/edit

我在这里有点担心,因为我直接从数据库中公开用户表主键 (ID)。我只是从 URL 中获取 ID(例如:来自上述 URL 的 1 和 2),使用 ID 查询数据库并获取用户信息(当然我正在清理输入 - 来自 URL 的 ID)。

请注意,我正在验证每个请求以检查版主是否有权编辑该用户

我做的安全吗?如果没有,我应该怎么做?

我可以想到一种替代方法,即为带有 25 个字符键的用户表设置一个单独的列,并使用 URL 中的键并使用这些键查询数据库。

然而,

  • 它有什么区别?(因为密钥现在暴露了)
  • 按主键查询比其他列更快产生结果
4个回答

您希望“隐藏”的唯一信息是序列:由于数据库将使用计数器分配主键值,因此看到主键值的人可以猜测相应用户帐户的创建时间除此之外,没有任何隐藏方案可能实际隐藏的其他信息。攻击者已经知道不同的用户是通过不同的键来引用的,这就是数据库“主键”的语义范围。

因此,除非您认为帐户创建顺序是需要隐藏的私人信息,否则我会说您的隐藏方案毫无意义。

一种简单的方法是使用 youtube 和其他网站使用的方法。这是 hashids ( http://hashids.org )。

使用这种方法,您可以提供如下链接:http ://www.example.org/user/fce7db/edit而 fce7db 将等于一个数字,例如:12

与在数据库中生成另一个随机哈希相反,这具有性能优势,因为您只需将其转换回一次,然后您就可以像以前一样通过原始主键在数据库中搜索。

为了让用户更难随机找到其他 ID,您可以使用一个秘密盐和最小长度来防止“暴力破解”它们。

通过使用一种秘密盐,人们仍然可以在http://www.example.com/image/c8yDa等情况下交换 URL 。

不可以。无论哪种方式,您都需要在 URL 中使用唯一标识符来标识特定记录。那可以是主键或其他东西。如果您需要隐藏顺序或序列,您可以使用带有随机且唯一字符串的第二列,例如 Z2wDKo0ubb1D2VngFh4N。

如果您想要更高的安全性,请使用 SSL。正如@eggyal 指出的那样,这并不会阻止用户看到 URL 和参数。

使用 SSL,URL 参数被加密并防止窃听。是的,我们现在知道 SSL 是有缺陷的,并不是真的那么安全,但它比不使用它提供了更多的安全性。但不要使用 URL 作为密码!与往常一样,使用 POST 登录和提交数据,使用 GET 检索信息。

请参阅https://stackoverflow.com/questions/499591/are-https-urls-encrypted

不在 URL 中使用机密信息的原因:DNS 请求可能未加密(但正如@tgies 在评论中指出的那样,请求部分不包括在内,因此此处没有 ID)、浏览器历史记录和服务器日志。

我创建了一些在 URL 中使用或不使用主键(或其他标识符)的系统。我们使用哪个完全取决于危害因素——例如,对于数据驱动的只读站点,我们使用 URL 中的主键;我们不在乎是否有人按顺序浏览产品。

对于有安全要求的系统,我们使用了以下两种方案之一,而不是使用顺序可预测的 id:

  1. 我们保留浏览器会话的关键信息。简单、直接,如果我们的服务器不安全,我们就会遇到更大的问题。
  2. 我们在创建记录时或仅针对会话生成了一个随机数(并检查了唯一性);并在 URL 中使用该随机数。

祝你好运,

拉里