Struts2又爆远程代码执行漏洞了,架漏CVE-2023-50164,架漏攻击者只需构造一个恶意的架漏上传文件名,就能直接往服务器上写webshell。架漏这已经不是架漏第一次了,从2016年的架漏S2-032到2017年的S2-045,再到如今,架漏这个老牌框架几乎成了漏洞的架漏代名词。可奇怪的架漏是,生产环境里跑着Struts2的架漏系统依然遍地都是,银行、架漏政府、架漏老牌电商,架漏全在用。架漏
框架漏洞的架漏本质,说白了就是框架替开发者做了太多“智能”的事。你以为你在处理一个普通的文件上传,但框架在背后帮你解析了文件名、解析了HTTP头、甚至调用了OGNL表达式引擎去“灵活”地处理参数。灵活是好事,可灵活过了头,就成了攻击者手里的刀。Struts2那次最著名的S2-045,就是因为它用OGNL解析Content-Type头,攻击者把恶意表达式塞进去,远程执行命令就跟喝水一样简单。
再看Spring,这家伙也一样。2022年的Spring4Shell漏洞,一个看似普通的JDK9+环境,配合Tomcat,加上Spring MVC处理参数的方式,就能让攻击者通过数据绑定写入恶意配置,直接拿下服务器。当时好多团队连夜打补丁,可补丁打完就没事了吗?框架的漏洞就像冰山,你看到的只是水面上那一角,水底下藏着的是整个设计思路的隐患。
我见过太多开发者,框架用了一两年,连它的请求处理链路都没搞明白。出了问题就查百度,查到什么是什么,根本不去想框架为什么要这么设计。他们不知道,框架为了“通用性”做的每一次抽象,都可能为攻击者留下一个可乘之机。就拿参数绑定来说,Spring MVC自动把HTTP参数绑定到对象属性,这个特性用起来是真方便,可一旦某个属性是内部敏感字段,攻击者就能通过构造参数名直接篡改它。
有个真实案例我记得很清楚。某电商平台用了某个老版本Spring,他们的订单接口有个参数叫price,开发者以为只从前端传过来的JSON里取值,可Spring的绑定机制会同时处理query参数和form参数。攻击者直接在URL后面加个?price=0.01,订单金额就被改写了。这不是SQL注入,也不是XSS,纯粹是框架特性被滥用。
框架漏洞还有个特点,就是修复起来特别麻烦。很多漏洞是框架核心设计层面的问题,不是改一行代码就能解决的。比如FastJson,从1.2.24到1.2.83,版本号跳了快六十个,可还是不断有新的反序列化绕过方式被发现。开发者被逼得没办法,只能自己写黑名单,可黑名单永远赶不上攻击者的脑洞。
说句实在话,这年头做Web开发,谁敢说自己不用框架?可用了框架,你就得接受它可能带来的风险。我的建议很简单:第一,别追新,但也不能太旧,选一个社区活跃、维护及时的版本;第二,关掉那些你用不到的特性,比如Struts2的OGNL,你要是用不到动态方法调用,就把它禁了;第三,也是最重要的,别指望框架帮你挡住所有攻击,你的业务逻辑里那些参数校验、权限控制,该写的还得写。
框架是工具,不是盾牌。它帮你省了造轮子的时间,可没帮你把坑填平。那些漏洞,说到底都是人写的代码,人总会犯错,可你得知道错在哪,才能防得住下一次。