连载中 12/16

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

2026-06-11 · 7665 阅读 · 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)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 4 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞