安全 · 权限设计
API 密钥泄露会发生什么:权限设计与最小授权
说到 API 密钥泄露,大部分人的想象是「币被提走了」。但真正常见的剧本不是这个——提现权限通常没开,对方拿不走币,却能用你的余额去做对他有利的交易。等你发现的时候,钱还在账户里,只是变少了。
这篇讲的是原理和后果:三类权限各自意味着什么、泄露之后攻击者能做什么又做不了什么、哪一道锁最划算、密钥通常从哪几个地方漏出去、发现之后按什么顺序处理。想要一份能逐条勾选的执行清单,用 API 安全自查清单;这里补的是清单背后「为什么」的那一半。
三类权限,先分清楚
不同平台的叫法略有差别,但创建 API 密钥时的权限基本都能归成三类,危险程度从低到高:
| 权限 | 能做什么 | 泄露之后意味着 |
|---|---|---|
| 只读 | 查行情、查余额、查历史订单 | 信息暴露,资金动不了 |
| 交易 | 下单、撤单、开仓平仓 | 钱拿不走,但可以被交易掉 |
| 提现 / 划转 | 把资产转出账户,或在账户之间划转 | 基本等于丢币 |
提现权限几乎永远不该开。理由很直接:自动化交易根本不需要它。策略脚本要做的是买和卖,不是把币搬走。你可能会想「万一我要写个自动归集的脚本呢」——那也建议手动做。一把带提现权限的密钥一旦泄露,几乎没有补救窗口,对方一条请求就能把资产转到自己的地址,链上转账不可撤销。省下的那几步手工操作,换不来这个风险。
还有一点值得提醒:有些平台的提现权限要配合提币地址白名单才真正生效,规则各家不同。但「加了地址白名单就安全」是个危险的简化——白名单本身也是账户设置,能不能被改、改完要不要等冷静期,取决于平台。真正稳的做法还是不开。
你的脚本是怎么拿着密钥去下单的
要理解密钥的风险,得先弄清楚它到底被谁用、以什么方式用。
你的策略跑在自己的电脑或一台服务器上,它不会「登录」交易平台,而是通过 HTTP 接口发请求。每条请求里带着 apiKey 和一段用密钥算出来的签名,平台收到后验证签名,确认「这是那把 Key 的持有者发来的」,然后照做。整个过程没有人工确认、没有短信验证、没有二次弹窗——密钥就是身份本身。
绝大多数人不会自己写签名,而是用现成的库(上图那类统一接口库是最常见的一种),把密钥填进配置,剩下的交给库处理。方便,但也意味着:你的密钥会以明文形式出现在某个配置文件、环境变量或代码里——而这正是它泄露的起点。
泄露之后,对方能做什么、不能做什么
假设你的密钥只开了只读和交易、没开提现,现在它落到了别人手里。
对方做不到的事:把币提走、把资产划转到别的账户、改你的账户设置、登录你的网页端。这些要么需要登录凭证,要么需要提现权限,一把交易密钥办不到。所以第一时间不必假设「钱已经没了」。
对方能做的,才是真正麻烦的部分:
- 用你的余额去砸盘或拉盘。攻击者在一个流动性很差的交易对上提前挂好自己的单,然后用你的账户市价对着打——你的钱以极差的价格成交,差价进了他的口袋。资金没有离开你的账户,但价值转移已经完成。这是很多人没想到的一种玩法,也是「只开交易权限就安全」这个说法最大的漏洞。
- 反复交易磨手续费。不需要多精巧,持续对敲就能一点点消耗你的余额。
- 动你正在跑的仓位。撤掉你的挂单、平掉你的持仓,或者在合约上给你开一个方向相反的大仓。
换句话说:没有提现权限,资产不会凭空消失,但它可以被交易成更少的钱。所以权限最小化必须和下面这道锁配合着用。
IP 白名单:性价比最高的一道锁
如果这篇只能留一条建议,是这条:给密钥绑 IP 白名单。
它的逻辑很干净——密钥只在来自指定 IP 的请求里才有效。泄露了也用不了,对方从自己的机器上调用会被直接拒绝。这道锁不依赖你记不记得改密码、不依赖你能不能及时发现异常,它是结构性的,而不是靠人自觉的。
成本也低。脚本跑在一台固定 IP 的服务器上(哪怕是最便宜的那种),配一次就完事。跑在家里宽带上、IP 会变的人会觉得麻烦——这恰恰是把策略挪到固定 IP 机器上跑的一个理由,不只是为了不断电。
但要清楚它挡不住什么:白名单防的是「别人拿你的密钥从别处调用」,防不住「你自己那台机器被入侵」。机器一旦被控制,请求就是从白名单里的 IP 发出的,这道锁形同虚设。所以它和权限最小化是叠加关系,不是替代关系。
密钥通常从这几个地方漏出去
密钥很少是被「黑」掉的,绝大多数是自己走出去的。按见得多的顺序:
- 提交进 Git。硬编码在代码里,随手一个 commit 就上去了。哪怕仓库是私有的、哪怕你后来删掉了那一行,历史记录里还在;而公开仓库上有人专门扫这类字符串。
- 写在截图里。发终端截图求助、录屏演示,配置文件那一行正好在画面里。密钥是长串随机字符,人眼扫过去不会注意,但它就在那儿。
- 贴进群里求助。报错信息连着配置一起复制粘贴,群里几百号人,你并不知道都有谁。
- 装了来路不明的「策略脚本」。这是后果最严重的一类:对方给你一个「稳赚的机器人」,让你把 apiKey 填进去。脚本连到谁的服务器、把密钥传去了哪,你完全不知道。凡是要你填 API 密钥的第三方程序,默认都该当成会拿走密钥来对待。
- 日志和报错。调试时把整个请求对象打印出来,密钥跟着进了日志文件,而日志的权限往往比代码宽松,还可能被上传到某个日志服务。
最小授权怎么落地
「最小授权」不是一句口号,拆开就是几条具体做法:
- 一个 Key 一个用途。看板和统计脚本用只读 Key,下单的策略用交易 Key,两把分开。看板那把泄露了,损失只是信息;而且出事时你能立刻定位是哪条链路漏的。
- 一套策略一把 Key。同时跑几套策略时别共用,出问题只停一把,不影响其他。
- 定期轮换,不用就删。每把 Key 都是一个敞口。临时测试用完立刻删,账户里挂着一堆早就忘了用途的 Key,是最常见的隐患。
- 密钥不进代码。放环境变量或不会被同步的本地配置文件里,并把配置文件写进
.gitignore。 - 跑脚本的钱和大仓分开。如果平台支持子账户,把量化资金单独放一份,主仓不参与。策略出错或者密钥出事,烧到的是有上限的那部分。
发现泄露之后,按这个顺序处理
- 先删密钥,别先查原因。登录账户,把那把 Key 直接删掉——不是改权限,是删。断掉对方的能力比弄清真相紧急,原因可以事后慢慢查。
- 停掉正在跑的程序。否则你的策略会因为 Key 失效不停报错,还可能触发一些奇怪的重试逻辑。
- 看挂单和持仓。撤掉所有不是自己下的挂单,检查有没有被开出来的仓位,合约那边尤其要看。
- 翻近期成交记录。找价格明显偏离的成交、你没下过的单。这一步决定了损失到底有多大。
- 换账户凭证。密码和二次验证一并处理,因为你还不确定泄露的只是密钥。
- 重建 Key,这次配齐最小权限和 IP 白名单。然后回头排查泄露路径:代码、截图、日志、装过什么脚本,一个个过。
顺序的重点全在第一条。很多人发现异常后的第一反应是截图、问人、研究到底怎么回事,而这段时间对方还在用。先把门关上,再研究门是怎么开的。
常见问题
只开了交易权限、没开提现,密钥泄露了资金还安全吗?
资产不会被直接提走,但不等于安全。拿到交易权限的人可以用你的余额在流动性差的交易对上以极差的价格成交,把差价转移给自己,也可以反复对敲磨掉手续费、平掉你的持仓,或者在合约上给你开一个反向仓位。钱还在账户里,只是变少了。所以权限最小化必须和 IP 白名单一起用。
提现权限什么时候才需要开?
对绝大多数做量化的人来说,永远不需要。策略脚本的工作是下单,不是把资产搬走。一把带提现权限的密钥泄露后几乎没有补救窗口,对方一条请求就能把资产转出去,而链上转账不可撤销。真有归集需求,建议手动操作,别为省几步操作换来这个敞口。
IP 白名单和权限最小化,哪个更重要?
两者挡的是不同的路,不能互相替代。权限最小化限定的是这把钥匙能开哪些门,IP 白名单限定的是这把钥匙在哪台机器上才有效。白名单挡不住你自己那台机器被入侵,权限最小化也挡不住有人在你允许的 IP 上用密钥下单。两个都做,才算合格。
几个程序共用一把 API 密钥可以吗?
不建议。共用意味着任何一个程序出问题,你都得停掉所有依赖这把 Key 的东西,而且出事时很难判断是哪条链路漏的。按用途分开:看板和统计用只读 Key,每套下单策略各自一把交易 Key。多建几把的成本很低,排查和止损时的收益很大。
别人给的策略脚本要我填 API 密钥,能用吗?
默认不要用。你无法知道那段代码把密钥发去了哪里,而它一旦拿到交易权限,就能用你的余额做对它有利的事。真要试第三方程序,至少确认代码可读、自己能看懂密钥的使用路径,并且先在只有极少资金的子账户上、配好 IP 白名单再跑。凡是承诺稳赚的,风险也不只在密钥这一层。
发现密钥可能泄露了,第一件事做什么?
直接删掉那把 Key,不是改权限,是删。断掉对方的能力比弄清原因紧急。删完再停掉本地程序、撤掉不认识的挂单、检查持仓和近期成交、更换账户密码与二次验证,最后才重建一把配好权限最小化与 IP 白名单的新 Key,并回头排查泄露路径。
把这几件事做完,API 密钥这一块的风险就从「看运气」变成了「有上限」。想按条勾一遍的,用 API 安全自查清单;还没走到写脚本这一步的,先看 量化交易到底是什么。另外提醒一句:密钥保管得再好,策略本身是亏的也没用——上真金之前,顺手对一遍 回测很漂亮,实盘就亏钱的五个原因。