有一个漏洞

 人参与 | 时间:2026-10-17 07:28:46

那天凌晨两点,有个漏洞我盯着屏幕上的有个漏洞报错日志,突然意识到——这个系统里藏着一个漏洞,有个漏洞而它已经存在了整整三年。有个漏洞

事情要从一次普通的有个漏洞代码审查说起。同事在合并请求里加了一行看似无害的有个漏洞校验逻辑,结果测试环境直接挂了。有个漏洞回滚、有个漏洞排查、有个漏洞再部署,有个漏洞折腾到后半夜。有个漏洞问题最终定位在一个老旧的有个漏洞工具函数上:它接收一个参数,判断类型时用了typeof,有个漏洞但那个参数可能是有个漏洞null。在JavaScript里,有个漏洞typeof null返回的是"object",于是后续所有逻辑都走错了分支。

这漏洞不复杂,甚至有点蠢。可它偏偏活过了三次重构、两次安全审计,还有无数轮单元测试。为什么?因为没人会传null进去——至少文档是这么写的。直到那天,上游服务因为网络抖动返回了一个空值。

我翻了下提交记录。最初写这个函数的人,注释里留了一句“参数不应为null”。然后他就离职了。后来接手的人默认这个约定成立,调用方也默认,连测试用例都只覆盖了正常路径。整个链条上,每个人都觉得别人会兜底。结果就是,一个显式的类型检查缺失,像一根松掉的螺丝,在机器高速运转时突然弹了出来。

这让我想起去年另一个项目。数据库连接池的配置里,最大连接数写的是100,但服务器文件描述符上限只有64。平时流量小,连接数从没超过20,谁也没注意。直到一次营销活动,并发请求冲上来,连接池疯狂创建新连接,系统直接卡死。运维查了半天,最后发现是配置文件里一个数字写大了。你说这是技术问题还是人的问题?我觉得都是。技术漏洞背后,往往是协作流程里的裂缝。

更早之前,我还见过一个前端漏洞。页面上的删除按钮,点击后只做了前端隐藏,没有调后端接口。用户刷新一下,数据又回来了。写这代码的哥们儿说,他以为后端同事会处理。后端同事说,接口文档里没写要删啊。你看,又是“我以为”。

漏洞这东西,不全是黑客攻击那种高深玩意儿。大多数时候,它就是一个没对齐的假设。A以为B会做,B以为A会做,最后谁都没做。代码不会撒谎,它忠实地执行了写下的逻辑,只是那逻辑和现实世界对不上。

回到凌晨那个bug。修复方案很简单,加一行if (arg === null) return。但真正让我后背发凉的是,如果那天同事没触发这个路径,它还会继续潜伏。也许下次爆发是在生产环境,在用户支付的时候,在数据迁移的深夜。一个三年前的小疏忽,像一颗定时炸弹,滴答滴答走到今天。

我关掉编辑器,窗外天快亮了。脑子里冒出一句话:所有漏洞都是人为的,而人总会犯错。区别只在于,有些错误被抓住了,有些还在某个角落安静地等着。

后来我在团队里推了一个规矩:任何函数入口,显式校验所有参数,哪怕文档说“不会为null”。写起来啰嗦,但至少不用再凌晨两点对着日志骂娘。有人嫌麻烦,我说你试试被一个typeof null坑掉整个周末的感觉。

漏洞不会消失。它们只是换了个地方,换了个形式,继续等着下一个“我以为”。

顶: 82448踩: 53681