连载中 12/16

ID 的安全账:别让 ID 泄了底

2026-06-11 · 7681 阅读 · 0 评论 · 0 赞

被爬虫光顾的一夜

第 11 篇夸完趋势递增,老王就挨了现实一巴掌:风控报警,某接口凌晨被同一 IP 刷了两万次,URL 长这样——/order/detail?no=202609140001、202609140002、202609140003……一路连号试过去。订单号规律得像流水线,爬虫顺着号遍历,撞上一个未做归属校验的老接口就拖走一单数据。递增的甜头刚吃完,可预测性的苦头跟着到账。这一篇算安全账。

ID 到底泄露了什么

把 ID 摆在明面上,等于给外人发了一份业务简报:

规模与增速:号段模式看跳变就知道每段发多快;雪花 ID 解出时间戳,单量曲线直接画出来——竞对盯你大促战报,不用看新闻,看号就行。

基础设施规模:雪花 ID 里 workerID 占着固定几位,解出来就是机器数量与拓扑;UUID v1 更狠,直接带 MAC 地址。

遍历入口:连号 ID 是给爬虫递梯子,配合没做归属校验的接口,就是数据泄露事故——业内管这类漏洞叫 IDOR(不安全的直接对象引用),常年霸榜 OWASP。

第一道防线:归属校验,没有商量余地

先把话说死:ID 不可预测是优化项,归属校验是必选项。拿到订单号的人必须先过登录态,再校验这单是不是他的——后端逐条判断,别信前端传参。这一步做了,ID 连号也只是难看;这一步不做,ID 再乱也挡不住越权。老王翻代码发现出事的接口压根没做归属判断,补上校验,漏洞先止血。但校验挡不住的还有一层:正常用户之间互相猜对方的单号做关联分析、给竞对递数据——这就要让 ID 本身不可猜。

第二道防线:外部 ID 与内部 ID 分离

架构上最干净的做法:内部主键照旧用趋势递增 ID 吃 B+ 树红利,对外暴露一个加密映射后的外部单号,两者一一对应,密钥只在服务端:

下单:内部 id=202609140001  对外 order_no=Enc(202609140001)=7f3kQ9mA
查询:按 order_no 反解出 id,再走内部逻辑
落库:订单表存 id,冗余一列 order_no 建唯一索引

加密映射的主流做法:

Feistel 网络:把 64 位 ID 对半拆开,轮函数迭代八轮,输出还是 64 位、一一对应、可用密钥解回来。长度不膨胀、格式不变(还能伪装成日期前缀的样子),Instagram 短链 ID 加密用的就是这套思路,工程验证充分。

格式保留加密(FPE/AES-SIV):标准密码学组件,安全等级高,适合合规要求严的场景,接入成本略高。

Hashids 类混淆:严格说是编码不是加密,密钥藏在参数里,防君子不防专家,仅适合无敏感信息的场景(比如防止文章 ID 被遍历抓取)。

顺便点名两个反面教材:MD5(id) 做外部号——查表穷举就破,且碰撞理论存在;简单 XOR 或仿射变换——拿两组样本做差就还原密钥。加密映射请走正规密码学路径,密钥进配置中心而非代码。

第三道防线:让 ID 本身不可猜

不想引入双 ID 映射的团队,可以在发号器上动刀,牺牲一点递增性换不可预测性:

跳号:号段模式每次取号随机丢弃一段(比如每次跳过 0-9 个),外部看到的号有洞、间距不均,遍历成本指数上涨。实现一行代码,对 B+ 树影响可忽略——洞也是趋势递增。

时间位加盐:雪花的时间位与真实时间做一次可逆变换(如异或一个固定盐再重排),不解盐就推不出真实单量时间曲线。注意别把盐设计成可被统计还原的线性关系。

限流与风控兜底:接口层对单 IP、单账号的 ID 探测频率限流,异常遍历模式直接进黑名单——这是所有方案的最后一道闸。

三层防线怎么选

方案防什么代价适用
归属校验越权(IDOR)每接口多一次判断必须做,无条件
外部 ID 加密映射遍历、规模泄露双 ID 维护、一次反解订单、用户等敏感对象
跳号/加盐遍历、增速泄露号有洞、少量改造不想双 ID 的中低敏场景
限流风控自动化攻击风控平台接入全站兜底

小结

安全账三句话:归属校验是根,缺了它 ID 再乱也是裸奔;外部 ID 加密映射是墙,Feistel 换来可预测与安全的兼得;跳号加盐是烟幕,一行代码提高遍历成本。老王的订单体系最终上了双 ID:内部号段 ID 伺候 B+ 树,外部 Feistel 加密单号伺候用户——两本账,各算各的。ID 体系还剩最后一块拼图:分库分表之后,ID 能不能顺便把路由也干了?下一篇讲分片基因。

☕
503

10 年全栈工程师 · 503咖啡馆主理人

#分布式ID#ID安全#IDOR#Feistel#加密映射

评论 (0)

热门推荐

连载中 11/22

主从搭建实操:从零配出一主两从

光讲原理不过瘾?手把手搭一主两从:my.cnf 六个参数、复制账号、GTID、CHANGE REPLICATION SOURCE TO、SHOW REPLICA STATUS 验收,附翻车排查清单。

#MySQL#主从复制#GTID#主从搭建#高可用
2026-05-07 · 10101 阅读 · 0 评论 · 0 赞
连载中 16/22

连接池:HikariCP 参数与连接风暴

连接池不是越大越好:8 核机器配 1000 连接反而更慢的数学原理,HikariCP 四个必调参数,maxLifetime 与 wait_timeout 的隐形陷阱。

#MySQL#连接池#HikariCP#maxLifetime#连接风暴
2026-05-10 · 9872 阅读 · 0 评论 · 0 赞
连载中 4/16

缓存穿透:恶意 ID 打穿 MySQL 的四道防线

请求的数据在缓存和数据库里都不存在时,缓存形同虚设。聊聊参数校验、空值缓存、布隆过滤器、限流熔断四道防线的原理与组合打法。

#Redis#缓存穿透#布隆过滤器#高可用
2026-05-16 · 9293 阅读 · 21 评论 · 287 赞