应不应该把主键 id 暴露在 url 上?

228 天前
 felix9ia

想请教一下大家是怎么做的?

比如访问一个电商网站的店铺页面的 url:

方式 1:使用自增的主键 id xxx/shop/123

方式 2:使用雪花主键 id 或者 guid

xxx/shop/1881238297653633026

xxx/shop/85d93ea0-3d43-48c5-99ec-e11f54655228

方式 3: 使用业务编号

xxx/shop/st_003

方式 4:

用 sqids 把所有的实体主键 id(private_id) 在转换 VO 时加盐转换成 (public_id) 返回给前端

相关讨论: https://www.reddit.com/r/csharp/comments/rg7xob/is_it_bad_to_expose_primary_key_to_the_user_if/

9122 次点击
所在节点    Web Dev
68 条回复
DonaldY
228 天前
@musi
@felix9ia
直接用自增 id ,方便爬虫穷举。

有权限的数据页面不应该用自增 id 在 url 上
Pdk5a8759cbeD6CH
228 天前
我想问一下自增的有什么风险?
jaylee4869
228 天前
@dylanqqt 没有做好数据权限控制会导致数据泄露的越权操作。
BeijingBaby
228 天前
安全性上讲,无所谓自增,有人说方便爬取,想多了。你随机 id 要爬取你也能爬到啊,只要数据是公开的,和自增和随机的没任何区别。
有时候更多的是考虑暴漏业务数据量,以及分布式的时候,才抛弃自增 id 。
zt5b79527
228 天前
@dylanqqt 简单来说,别人能猜到你的数据量。比如说订单号自增,竞争对手就能知道你的订单量。比如之前 b 站的 bv 号,最初好像也是自增的,竞争对手就能知道平台的投稿量,后来就换成随机的了(应该不全是这个原因,但是肯定有这方面的考量)
esee
228 天前
主键用的自增 ID, 后端接口查询的时候,sql 语句对 id 加密查询出来,我是这样做的.
musi
228 天前
@DonaldY #21 简单的数字我也可以穷举吧
zjsxwc
228 天前
自增 id 方便调试和 dba 维护,大部分时候自增 id 就够用了,
我只在 serverless 系统上看到用 uuid 的
wangtian2020
228 天前
可以暴露,暴露在 url 中与暴露在请求体里有什么区别。
问题是不要使用自增 id 暴露网站后台的规模!
订单 id 自增暴露每日订单数量,商品 id 自增暴露订单数量
Pdk5a8759cbeD6CH
228 天前
@zt5b79527 这种算不上什么,自增 id 可以从 1 开始自增,也可以从 10000000 开始自增,别人咋看?至于小公司根本不在乎这个 id 暴露。
chendy
228 天前
暴露 id 本身没啥问题
暴露 id + 自增 id 可能导致的问题:
1. 对外的系统,纯自增 id 可以推算出数据增长量,暴露业务情况
2. 如果权限做的不好,用户或者爬虫可以通过 id 遍历全部数据
处理方式也很简单:
1. 用一些操作对数据进行加密/编码
2. 完善权限,完善风控
yelog
228 天前
@dylanqqt 容易被暴力攻击越权漏洞, 假如微博的私信列表有越权漏洞

你在进入微博的私信页面, 发现获取私信列表的接口是 weibo.com/p_message/16645, 然后你把最后的数字(id) 改为 1, 发现获取到管理员 admin 的私信列表了哈哈哈, 然后依次加 1, 可以非常快把微博的所有用户的私信列表全部下载下来

如果不是自增的, 比如 UUID, 尽管知道这个接口越权漏洞, 但是鉴于 UUID 的随机性和位数, 用户隐私泄漏的风险就非常小
TimePPT
228 天前
@chendy 完全同意,其实主要问题就是推断业务增长情况,和遍历爬虫(一个冷知识:QQ 邮箱的数字 @qq.com 也有类似问题所以一开始入信反垃圾策略就很严格),其他没啥大问题。

我新项目一般数据库用 PostgreSQL ,唯一 id 使用 uuidv7 ,传给前端 url 外显时候使用 url safe 的 base64 显示了,除了丑点没啥其他副作用。
cxxlxx
228 天前
liuidetmks
228 天前
@dylanqqt 从 1w 开始,并不能起到很大作用,人家只有作差分就能获取你某段时间内业务规模了
自增 id 也有其他风险,
比如某个接口配置失误,通过订单号直接查询数据,还是比较危险的
importmeta
228 天前
里面逻辑再拿用户 id,加一层保险
SoyaDokio
228 天前
根据 RESTful 语义原则,当然是把 ID 放在 URL 里更好,但仅限于 UUID 或其他类似主键。
自增主键的话,建议还是隐藏起来,以免用户可以轻松批量暴库。
default996
228 天前
通常建表时我会创建 id,created_at, updated_at
然后一般情况下我会使用自增 ID;
特殊情况下,我会使用 id+created_at ,只有两个都匹配到才能查询到记录
Reficul
228 天前
自增 ID 可能会暴露你们业务一天有多少数据,比如订单量之类的。之前我们懒惰 fix 这个问题的方法是随机跳过部分数字来给数据投毒。
voy
228 天前
hackernews is self increased. done.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1106781

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX