当前位置: 当前位置:首页 > 休闲 > 扫描不出漏洞正文

扫描不出漏洞

作者:热点 来源:探索 浏览: 【大 中 小】 发布时间:2026-10-17 06:23:16 评论数:

上周三,扫描我把那个跑了六年的不出老项目从仓库里翻出来,重新编译。漏洞代码没动过,扫描依赖没升级,不出连IDE都是漏洞当年那版。结果扫描器一跑,扫描满屏红。不出

一百三十七个高危漏洞。漏洞我盯着报告看了半天,扫描心里清楚得很——这里面至少一百个是不出误报。不是漏洞自我安慰,是扫描那些漏洞依赖的库版本,跟项目里实际用的不出根本不是一回事。扫描器读的漏洞是pom.xml里的声明,可项目里真正加载的jar包,早就被运维手动替换过三轮了。

这事挺讽刺的。安全团队每个月发报告,催着修漏洞,可他们手里的工具连代码到底跑的哪个版本都搞不清楚。我试过跟他们解释,对方回一句“以扫描结果为准”。行吧,你扫你的,我跑我的。

后来我把扫描器日志翻出来逐条对。有个CVE说Jackson反序列化漏洞,影响2.9.10以下版本。项目里确实声明的是2.9.8,但实际classpath里躺着的,是运维从另一个项目拷过来的2.11.4。扫描器只看声明文件,不看运行时。这漏洞修不修?修个空气。

还有更离谱的。有个依赖叫commons-collections,扫描器报3.2.1版本有反序列化漏洞。可这个依赖在项目里压根没被加载过——它是某个测试库的传递依赖,而那个测试库在打包时就被exclude了。扫描器不管这些,只要在依赖树里出现过,就给你标红。

我数了数,真正需要处理的漏洞,大概二十个出头。剩下那一百多个,要么是版本对不上,要么是依赖根本没进运行时,要么是漏洞触发条件跟项目实际用法完全不沾边。比如有个SQL注入漏洞,要求把用户输入直接拼接到order by后面。我们项目里order by的字段是写死的枚举值,用户输入连碰都碰不到。这漏洞怎么触发?扫描器说“存在风险”,可风险在哪儿?

安全团队不认这些。他们的KPI是漏洞数量下降,不是漏洞真实性。我提过几次误报,对方让我提供“证明”。怎么证明?把运行时classpath导出来?把调用链打出来?我试过一次,导了三百多行依赖树,对方看了一眼说“太复杂了,还是按扫描结果修吧”。

修就修吧。升级Jackson到2.11.4,结果跟Spring Boot 1.5不兼容,启动直接报错。回滚。升级commons-collections到3.2.2,测试环境跑了一周没出事,上线第二天支付模块挂了。查了半天,是某个老代码用了3.2.1里一个被移除的API。回滚。来回折腾三趟,最后我学乖了,在pom里加了个exclusion,把扫描器报的那个依赖直接排掉。扫描器再跑,漏洞没了。实际上代码一行没改。

这事让我想起以前在上一家公司,安全部门买了个商业扫描器,一年几十万。每次发版前必须扫,扫出高危就得修,不修不给上线。有次一个项目扫出两百多个漏洞,团队加班修了两周,上线后一个都没触发。后来CTO问安全负责人:“这些漏洞到底有没有被利用过?”对方说:“目前没有。”CTO说:“那你们怎么证明修了有用?”对方说:“那你们怎么证明不修没用?”

死循环。

扫描器是个工具,工具就有盲区。它不知道你的代码怎么跑,不知道你的依赖怎么加载,不知道你的业务逻辑长什么样。它只会对着声明文件念经。可安全流程偏偏把扫描结果当圣旨,把误报当KPI,把修漏洞变成改配置。最后大家都很忙,忙着把红点变绿,至于漏洞到底在不在,没人关心。

我现在学聪明了。扫描报告出来,先看CVE编号,再查实际依赖版本,最后翻代码确认调用路径。三步走完,该修的修,不该修的写个说明存档。安全团队再来催,我就把说明甩过去。对方有时候认,有时候不认。不认的时候,我就把扫描器日志和运行时classpath一起打包发过去,附一句:“您看哪个是真的?”

多数时候,对方不回了。