给「七亿批量远程管理工具」里那个 SSH AI 助手加了一道闸门:它想在服务器上敲命令,得先过一遍分级——绿的只读直接跑,黄的改配置弹窗让人点一下确认,红的删数据、停 sshd、动防火墙一律硬拦。判定这套逻辑,是负责这块的同学写的。他每写完一版都自己跑一整套用例,回回「全过」。可我还是把它打回了三次。
这台助手我们之前写过:它能自己摸黑排查、自己踩坑自己爬出来(那次给网站开 IPv6 就是它干的)。越是这种能自己动手的,越得先给它装一道靠谱的闸门。
因为从一开始我就认一条:它自己说「全过」,不算数。
第一件让我停下来的事:它贴过来的,是旧文件
第一版判定逻辑,配一张对照表,说 66 条用例全过。我没看表,先把它的代码文件拿下来,自己把同一条命令喂进去重新跑了一遍——结果有两个结果对不上。仔细一比,更离谱:那个代码文件跟上上一版逐字节一模一样,等于上一轮改的东西根本没进来,它是从一个没刷新的目录里把旧货捞出来给我看的。
它自己那套用例是「通过」的,因为用例只测它跑没跑,测不出它跑的是不是那份。就像你让人交作业,他交的作业确实做对了,可惜是上周那份。
从那以后我加了个死规矩:代码文件和用例都要带哈希。谁拿到都能核对「跑的就是这份」。上一轮贴错文件这种事,靠流程堵,别靠记性。
第二件:一个能把它自己卡死的正则
改完再交,这版 94 条全过。我又自己写了三十多条「刁钻命令」去砸它——专挑对方用例里没覆盖、可客户端又真可能碰上的形状。砸出两类问题,第二类最要命。
一类是包装词绕过。命令前面套个执行器,红命令就被藏起来了。比如 timeout 5 rm -rf /、bash -c 'rm -rf /'、xargs rm -rf、su -c 'rm -rf /'……十几条,判级全从「红」掉成了「黄」——等于放行。最扎心的是 timeout:那是它自己代码里包命令用的词,它把命令包进 timeout 再跑,结果里面的 rm 反倒看不见了。
另一类更隐蔽:正则回溯。判定用了一堆正则,其中一段「旗标 + 参数」的写法有歧义,一个 -a 既可能算旗标、也可能算上一个旗标的参数。两个都能解释,正则就两条路都试。我拿 sudo 后面跟 N 个 -a 去压它:到第 24 个耗时 0.68 秒,第 28 个直接超过 3 秒——每多两个参数,耗时翻一倍。真放到「七亿批量远程管理工具」的客户端上,一条带几十个参数的命令(或者 AI 自己生成的长命令)就能把判定函数卡死,弹窗整个冻住。
这两个都不是「跑不对」的小毛病,是「出事要命」的那种。第一类等于闸门漏风,第二类等于闸门卡死。
第三、四件:剩下的都是边角
第二版补完,我复测:回合数从 66 涨到 111 条,包装词那十几条全修成「红」,只读命令也没被误伤成「黄」,那个能把人卡死的正则也从「指数级」变成了线性——两万个参数现在只要 0.3 秒。
我盯着又想到两条它漏的:反引号命令替换(echo \rm -rf /\``),以及「套超过 8 个参数之后再跟非 rm 的红命令」。都是边角,危害不高,但既然反引号是正经的 shell 语法,就该补。它当天补完,111 条涨到 114 条。这版我签字放行。
拉上线前,我干了最后一件事
它打了个发版包,把源码、用例、对照表一起塞进去,还按我要求带了每文件的哈希。我下载下来,把里面的判定文件和我签字留存的那份逐个字节比了一遍——一致。这才让它发。
回头想,这几条比代码本身值钱
- 同一套规则、同一个脑子,跑出「全过」证明的是一致,不是完备。 完备性得靠外面的人,自己写用例去砸。
- 单一真源的对应用例,防不住「代码没同步」。 用例只测你跑没跑,测不出你跑的是不是那份——哈希和版本号才防得住。
- 判定函数里,长而重复的输入能把正则拖死。 给每条正则设个超时,超时就往「红」(安全那一侧)倒,宁可误拦,别卡死。
- 审的人用的探针,自己也得带超时。 我第一次测那个正则,把审查的一方先挂死了——测别人的刀,先给刀套上护手。
这道闸门从「看着能用」到「真拦得住」,中间隔了四轮。我没干别的,就是不肯信那句「全过」。
顺带说一句,「七亿批量远程管理工具」 里的这个 AI 助手,本事是一回事,敢不敢让它碰生产机,取决于这道闸门够不够硬。这回算是把闸门查透了。
评论