游客发表
2021年冬天,系统Log4j那个漏洞爆出来的安全时候,我正跟一个做电商的漏洞朋友吃饭。他手机响个不停,包括运维团队在群里刷屏,系统说服务器上跑了两年多的安全日志组件突然变成了一个远程代码执行的后门。那天晚上他们通宵打补丁,漏洞第二天还是包括被扫了一轮。一个被无数项目引用的系统开源库,就因为一个JNDI查询没做限制,安全差点把半个互联网掀翻。漏洞这件事说明一个很朴素的包括事实:系统安全漏洞从来不挑你代码写得多漂亮,它只找你没想到的系统地方。
漏洞这东西,安全本质上就是漏洞系统里“本不该存在却能存在”的东西。可能是代码逻辑写岔了,可能是配置留了后门,也可能是设计时压根没考虑某种输入。按我的经验,常见的大致分几类。
注入类漏洞是最老牌也最顽固的。SQL注入、命令注入、LDAP注入,名字不同,套路一样——把用户输入当代码执行了。我见过一个后台管理系统,登录框直接拼SQL字符串,输入 ' or '1'='1 就能进去。开发图省事,觉得内网系统没人攻击,结果被一个离职员工顺手薅走了全部订单数据。这类漏洞的修复其实不复杂,参数化查询、输入白名单,但架不住有人偷懒。
越权访问是另一种高频问题。用户A能看用户B的订单,普通账号能调管理员接口。有次我帮一个朋友看他们的小程序,改一下URL里的用户ID,就能看到别人的收货地址和手机号。开发把权限校验写在了前端,后端接口裸奔。这种漏洞在业务快速迭代的项目里特别常见,因为大家忙着加功能,没人回头检查“这个接口该不该让这个人调”。
内存安全问题在C/C++系统里像慢性病。缓冲区溢出、释放后使用、空指针解引用,随便一个都能让进程崩溃甚至被利用。Windows的蓝屏漏洞、安卓的提权漏洞,很多都出在这。Rust这几年火起来,很大程度就是因为编译器帮你挡掉了一大批内存错误。但存量系统太多,不可能全部重写,只能靠静态扫描和fuzzing慢慢磨。
配置和逻辑漏洞往往最容易被忽略。默认密码没改、调试接口没关、云存储桶权限设成公开。有个做SaaS的团队,把测试环境的数据库连接串提交到了公开的GitHub仓库,里面存着真实用户数据。还有逻辑漏洞,比如优惠券可以无限领、支付金额前端可改。这类问题扫描器扫不出来,得靠人对着业务流程一点点推演。
供应链漏洞是这几年越来越突出的。你用的npm包、pip包、Docker镜像,任何一个环节被投毒,整个系统就沦陷。2020年SolarWinds事件,攻击者篡改了软件更新包,导致美国政府多个部门被入侵。Log4j也是供应链问题——你写自己的代码没问题,但你依赖的库有问题。现在很多团队开始做SBOM(软件物料清单),至少知道自己用了什么。
零日漏洞听起来最吓人,但实际遇到的比例并不高。大多数被利用的漏洞,其实补丁早就发布了,只是没人去打。我见过一台服务器跑了五年没重启,内核版本还是2.6,上面跑着对外服务。问为什么不升级,答“怕升级出问题”。这种心态比漏洞本身更危险。
漏洞不会消失。系统越复杂,交互面越大,出问题的概率就越高。能做的无非是:少写拼字符串的代码,权限校验别偷懒,依赖库定期更新,配置别用默认值。听起来都是常识,但常识往往最难坚持。
友情链接