|
上周三凌晨两点,漏洞安全组的扫描老张在群里甩了一张截图——某个内部管理后台的登录页面,URL后面跟了一串奇怪的整改参数,页面直接返回了数据库的报告报错信息。他什么都没说,漏洞只打了个“?扫描”。我知道,整改又该干活了。报告 这次漏洞扫描覆盖了公司对外的漏洞12个业务系统,扫出来37个漏洞。扫描高危9个,整改中危18个,报告剩下的漏洞是低危和误报。真正让我头疼的扫描不是数量,是整改分布——那9个高危里,有6个集中在两个“老系统”上。所谓老系统,就是三年前外包团队交付后、原班人马早已解散、代码没人敢动的那类项目。 那些被扫出来的东西,到底长什么样 举几个具体的。某后台接口未做权限校验,普通用户改个URL参数就能查看全部订单,包括客户姓名、手机号、收货地址。这个漏洞的CVSS评分是8.1,利用门槛几乎为零——会用浏览器就能干。另一个是文件上传点,前端限制了后缀名,后端居然信任了前端传来的文件名,改个包就能传jsp。还有一个更离谱的,测试环境的数据库连接串硬编码在JS文件里,账号是root,密码是公司缩写加123。 SQL注入也有,但不像前几年那么泛滥。这次扫出来的两个注入点都在查询接口的排序字段上,开发人员大概觉得“排序参数用户又看不见”。实际上抓包改一下orderBy,报错信息直接把表名和字段名全吐出来了。 为什么修起来比扫出来难十倍 扫描器跑完只要四十分钟,整改花了两周还没完全收尾。权限校验那个漏洞,修复方案是在接口层加一个角色判断,代码改动不到二十行。但那个接口被七个前端页面调用,其中三个页面是运营自己用低代码平台搭的,没人知道它们具体传了什么参数。改完之后,运营那边直接炸了——有三个报表页面白屏。最后只能回滚,换了个更保守的方案:在网关层加规则,只放行已知的合法参数组合。 文件上传那个更典型。开发说“我加了白名单”,我让他把代码发过来。白名单是这么写的:if(fileName.endsWith(".jpg") || fileName.endsWith(".png"))。文件名是shell.jsp.jpg,照样过。这不是技术问题,是意识问题。后来我们统一换成了检查文件头魔数,并且把上传目录设成了不可执行。 整改报告里不会写的东西 报告上只会写“已完成修复,复测通过”。实际上每个漏洞背后都有一堆扯皮。业务方说“这个功能上线三年了没人发现,你们安全部是不是小题大做”。运维说“改可以,但得走变更流程,排期到下个迭代”。开发说“这个框架太老了,升级风险太大,能不能先加个WAF规则顶一下”。 我个人的判断是:WAF能挡掉大部分自动化扫描和脚本小子,但挡不住真正盯着你系统的人。那个未授权访问的漏洞,WAF规则根本拦不住——因为请求看起来完全正常,只是参数值不同。最后我们还是在代码层做了修复,虽然过程曲折。 几个真实的教训 扫描器报的漏洞,优先级不能只看CVSS评分。那个文件上传漏洞评分7.5,但实际危害远高于评分8.1的未授权访问——因为上传webshell之后就是服务器权限,内网横向移动的门就开了。我们后来调整了排序逻辑:能直接 getshell 的排第一,能批量泄露数据的排第二,反射型XSS这种排最后。 老系统的漏洞修复,别想着一次性全改完。挑最要命的那两三个先堵上,剩下的排期慢慢来。指望外包留下的烂代码在两周内焕然一新,不现实。我们这次的做法是:高危漏洞必须当个迭代修完,中危给两个月缓冲期,低危随版本迭代顺带处理。 复测的时候别只测修没修好,还要测有没有引入新问题。那个权限校验的修复,第一版改完之后普通用户确实看不了订单了,但管理员账号也看不了了——判断条件写反了。这种错误扫描器扫不出来,只能靠手工验证。 最后说一句,漏洞扫描报告不是给领导看的表演,是给干活的人看的清单。每一条都得能落到具体的人、具体的代码行、具体的修复时间。否则扫一百遍也是白扫。 |