应不应该把主键 id 暴露在 url 上?
想请教一下大家是怎么做的?
比如访问一个电商网站的店铺页面的 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) 返回给前端
相关讨论:
www.reddit.com/r/csharp/comments/rg7xob/is_it_bad_to_expose_primary_key_to_the_user_if/
不是自增的就行
在绝大部分场景下,我推崇方案 1 ,如果有产品端/安全端的特殊需求,我会考虑方案 3 ,只有再极少数场景下,比如日志追踪等,我会考虑 2
原贴编辑过了吗?我这里的方案 3 指的是加盐,方案 2 指的是 uuid
我(前端)做过的功能,后端给几乎都是用的自增 ID ,极少数场景才会用 2 ,其他目前没遇到
是的,不好意思,我刚刚改了一下。
其实方案 1 的自增有明显的缺陷,不应该被推荐把? 用 sqids 加盐我觉得也是少数场景,比如用户主页这种。
2 就够用了,还是像楼上说的,只要不是自增就行了。
其实,我的这个问题有场景限制,就是在客户端,而不是后台管理页面。
如果是后台管理,我觉得暴露自增 id 没有关系。
方案 4 有一个好处就是,定期更换盐,可以让链接失效,当然让链接失效有好处也有坏处
嗯,如果是用户端,个人感觉还是不要暴露自增 id ,总感觉不安全
自增 id 除了暴露数据量之外,其他我也没觉得会有啥缺陷,而“暴露数据量”这件事也只有少数场景下才值得被关注,这些场景下就需要具体问题具体分析,比如订单相关场景,其实订单号比 ID 更像事实上的主键(我个人喜欢在绝大多数场景下都保留自增 ID ),业务上基本使用订单号而非主键。
肯定不能用自增,首先安全那关就过不去,可以被黑产猜测到数据,遇到爬虫,直接把你整个业务的数据都扒下来。用 md5, uuid, 雪花都行
目前项目都用 ULID
暴露自增 id 有什么问题吗?
我没见 v2 有什么安全性问题啊
数字没问题啊, 只要不是自增就行 足够大 轮训不全的.
V2EX 用的是自增 id ?
www.hesudu.com/t/1106781
t 后面的不就是帖子 id 么,你加一减一不也能看到其他帖子么
也可以用对称加密算法加个密,不知道密钥的话也破解不了
卧槽,还真是
其实 暴露在 url 上和暴露在接口 json 中没啥区别,不自增就行
飞书一样暴露出来的
京东这一串应该也是自增。
item.jd.com/product/7323507.html
直接用自增 id ,方便爬虫穷举。
有权限的数据页面不应该用自增 id 在 url 上
我想问一下自增的有什么风险?
没有做好数据权限控制会导致数据泄露的越权操作。
安全性上讲,无所谓自增,有人说方便爬取,想多了。你随机 id 要爬取你也能爬到啊,只要数据是公开的,和自增和随机的没任何区别。
有时候更多的是考虑暴漏业务数据量,以及分布式的时候,才抛弃自增 id 。
简单来说,别人能猜到你的数据量。比如说订单号自增,竞争对手就能知道你的订单量。比如之前 b 站的 bv 号,最初好像也是自增的,竞争对手就能知道平台的投稿量,后来就换成随机的了(应该不全是这个原因,但是肯定有这方面的考量)
主键用的自增 ID, 后端接口查询的时候,sql 语句对 id 加密查询出来,我是这样做的.
#21 简单的数字我也可以穷举吧
自增 id 方便调试和 dba 维护,大部分时候自增 id 就够用了,
我只在 serverless 系统上看到用 uuid 的
可以暴露,暴露在 url 中与暴露在请求体里有什么区别。
问题是不要使用自增 id 暴露网站后台的规模!
订单 id 自增暴露每日订单数量,商品 id 自增暴露订单数量
这种算不上什么,自增 id 可以从 1 开始自增,也可以从 10000000 开始自增,别人咋看?至于小公司根本不在乎这个 id 暴露。
暴露 id 本身没啥问题
暴露 id + 自增 id 可能导致的问题:
- 对外的系统,纯自增 id 可以推算出数据增长量,暴露业务情况
- 如果权限做的不好,用户或者爬虫可以通过 id 遍历全部数据
处理方式也很简单: - 用一些操作对数据进行加密/编码
完善权限,完善风控
容易被暴力攻击越权漏洞, 假如微博的私信列表有越权漏洞
你在进入微博的私信页面, 发现获取私信列表的接口是 weibo.com/p_message/16645, 然后你把最后的数字(id) 改为 1, 发现获取到管理员 admin 的私信列表了哈哈哈, 然后依次加 1, 可以非常快把微博的所有用户的私信列表全部下载下来
如果不是自增的, 比如 UUID, 尽管知道这个接口越权漏洞, 但是鉴于 UUID 的随机性和位数, 用户隐私泄漏的风险就非常小
完全同意,其实主要问题就是推断业务增长情况,和遍历爬虫(一个冷知识:QQ 邮箱的数字 .com 也有类似问题所以一开始入信反垃圾策略就很严格),其他没啥大问题。
我新项目一般数据库用 PostgreSQL ,唯一 id 使用 uuidv7 ,传给前端 url 外显时候使用 url safe 的 base64 显示了,除了丑点没啥其他副作用。
推荐 sqids.org/?hashids 转换
从 1w 开始,并不能起到很大作用,人家只有作差分就能获取你某段时间内业务规模了
自增 id 也有其他风险,
比如某个接口配置失误,通过订单号直接查询数据,还是比较危险的
里面逻辑再拿用户 id,加一层保险
根据 RESTful 语义原则,当然是把 ID 放在 URL 里更好,但仅限于 UUID 或其他类似主键。
自增主键的话,建议还是隐藏起来,以免用户可以轻松批量暴库。
通常建表时我会创建 id,created_at, updated_at
然后一般情况下我会使用自增 ID;
特殊情况下,我会使用 id+created_at ,只有两个都匹配到才能查询到记录
自增 ID 可能会暴露你们业务一天有多少数据,比如订单量之类的。之前我们懒惰 fix 这个问题的方法是随机跳过部分数字来给数据投毒。
hackernews is self increased. done.
有时候杀鸡用不上牛刀。
其实还有 1 种简单方案,叫 hashid, 几十种语言的实现都有, github 可用搜到,可以在纯数字和"hashid"之间互相转换,既不直接暴露主键数字 id 给前端,无法被人直接遍历,同时也不增加后端复杂度。
Hashids 改名叫 Sqids 了. sqids.org/
原来 已经提出来了,刚开始没注意到。
自增的也无所谓,需要安全的地方,需要其它权限鉴定逻辑。
如果你用 innodb 的话,可以把 update 全部改成 insert ignore on duplate update ,你就能得到一个超音速自增的主键(狗头
用自增的一些缺点:
1 ,暴露业务数据规模,著名的瑞幸咖啡那件事就是被人蹲点捡小票,通过 ID 推算真实业务量
2 ,方便爬虫写脚本抓数据
3 ,存在缓存击穿问题???
要看业务是不是数据都公开,京东的商品,论坛的帖子,这种无所谓。资源要做隔离的就需要考虑隐藏了
暴露有什么影响吗?
有些 ID 暴露也无所谓啊,就例如这个帖子的 ID 不就在 url 上
涉及到隐私和安全的可以考虑加密或雪花或其他方案加密。
正常用的无所谓的,做好暴露后问题的处理就行。
我们有个项目是直接用 ID 异或一个较大的数给前端就行了,然后再异或回来
#30 单单业务规模这一点,确实对小公司可能不算什么,那大公司呢?如果是年营收上百亿,竞争对手虎视眈眈的上市公司呢?对于大公司来说,安全才是第一位的。竞争对手可能已经通过各种渠道收集了你各种各样的信息,再加上这一点交叉验证,底裤都给你扒出来。
snowflake id 就足够了,别的纯属想太多
看完这贴我就把 v 站的第 1,10,100,1000,10000,100000,1000000 贴看了一遍
对很多业务来说这么轻易的能跳转是不可接受的
自增 id 然后商户可以 缴纳 30 元 自定义一个“靓号”
不连续就行了
可以考虑 hashids 对主键进行映射
ic-item.jd.com/100143612769.html 京东算不算大公司?只能说这并不算什么大不了的事情。
危险是因为接口配置失误了危险,并不是自增 id 危险。就像支付宝这次打折 20%一样,并不是开发这个打折 20%的功能很危险,是因为配置错误了很危险。
- 不是自增就行
但如果是大家喜欢的 MySQL 嘛,那就加盐吧
自增危险是你的接口处理权限有问题,就和"把某个东西藏起来不想让别人找到"在应用密码学里面提到过是一件不靠谱的事情,做好接口防范才是正道.
2 楼正解
主键暴露不暴露得看你的主键有什么意义。
像 v2 或者贴吧、抖音、b 站的帖子 id 暴露就暴露了,除特殊板块做鉴权拦截外,其它帖子本来就允许你随便看,那数字反倒是一个很容易记忆的东西, 比如 5 、6 年之前 b 站分享很多时候人们还是直接说 av 号的。
像淘宝京东这类 电商,他们肯定不希望可以从订单号看出什么规律,且不说万一有什么权限 bug ,导致瞎拼的 id 可以访问到其它人的数据,但从规律自增让其它竞争对手可以统计他们每日交易量就是个大风险。
id 暴露很正常,但是还是不要暴露自增的吧
安装了宝塔,尝试在 443 端口接受 UDP 流量后转发 发现压根就接收不到 UDP 流量,宝塔的技术说 443 端口是无法设置 udp 的.. 我想着 443 只是一个端…
如题 本来公司批量团购的某宝 Cursor 半价,今天续费时和我说 Cursor 春节后锁区了,地区不对的充值会自动退款。 哥们又上宝宝调研了一下,发现还有售价一百多的代充。 …
最近用 cursor ,感觉 claude3.5 的智力在降低,你们有没有这种感觉? 以前用 chatgpt 等其它 AI 等时候也发现过这种现象,非常看运气,同一套问题,在不…