游客发表
2021年底爆发的组件Log4Shell漏洞,把Java生态的存漏供应链安全问题直接掀到了台面上。一个日志组件,组件几乎无处不在,存漏一个JNDI注入就能远程执行代码,组件全球多少企业连夜打补丁。存漏这事说明一个问题:Java的组件组件漏洞,杀伤力往往不在语言本身,存漏而在那些你根本没注意过、组件却被无数项目间接引用的存漏第三方库。
先说Spring家族。组件Spring Framework本身出过不少CVE,存漏比如Spring4Shell(CVE-2022-22965),组件通过数据绑定机制在特定条件下实现远程代码执行,存漏影响面覆盖大量Spring MVC和WebFlux应用。组件Spring Cloud Gateway也没消停,CVE-2022-22947允许攻击者通过Actuator端点注入SpEL表达式,直接拿下服务器。Spring Boot的Actuator如果暴露在外又没做认证,基本等于把后门敞开。
Struts2是另一个重灾区。从S2-001到S2-061,OGNL表达式注入的漏洞几乎年年都有。2017年的S2-045,Content-Type头里塞一段OGNL就能执行任意命令,当时国内大量政企网站中招。Struts2的问题在于它把用户输入和表达式求值绑得太紧,架构层面的设计缺陷导致补丁打了一轮又一轮,新绕过手法还是层出不穷。
Fastjson,国内开发者太熟悉了。autotype机制导致的反序列化漏洞,从1.2.24一直修到1.2.80,每次以为修好了,过段时间又冒出绕过。攻击者通过精心构造的JSON payload,利用JNDI或TemplatesImpl等链子实现RCE。很多团队后来干脆换成了Jackson或者Gson,不是Fastjson不好用,是安全债还得太累。
Log4j 2的Log4Shell(CVE-2021-44228)不用多讲,JNDI lookup功能被滥用,${ jndi:ldap://...}这种字符串出现在任何被记录的地方——User-Agent、用户名、聊天消息——都能触发。更麻烦的是Log4j 1.x虽然官方停止维护,但仍有大量老系统在跑,CVE-2019-17571的反序列化漏洞同样致命。
Shiro的rememberMe反序列化漏洞也值得提。CVE-2016-4437,AES密钥硬编码在代码里,攻击者可以伪造cookie触发反序列化。很多甲方渗透测试报告里,Shiro这个点几乎是标配。修复方式倒不复杂,换个随机密钥就行,但问题是大量项目从来没人动过那个默认配置。
XStream、Jackson-databind、Groovy、Commons-Collections、Commons-BeanUtils……这份名单还能拉很长。Jackson-databind的enableDefaultTyping一旦开启,配合特定gadget链就能RCE,CVE编号多到安全圈调侃“Jackson的CVE是按月发的”。Commons-Collections 3.1的反序列化链更是经典,ysoserial工具里一大半payload都依赖它。
我的判断是:Java组件漏洞频发,根子在于生态太依赖“传递性依赖”。你写了个简单的Web服务,pom.xml里就几个直接依赖,但mvn dependency:tree一拉,底下挂着上百个间接依赖。任何一个出了洞,你的应用就暴露了。SCA工具能扫出来,但扫出来之后升级又可能引入兼容性问题,很多团队就拖着,拖到出事为止。
实操层面,几个习惯能救命:别用Fastjson的autotype,Spring Boot Actuator别裸奔,Log4j 2升到2.17以上,Shiro换掉默认密钥,定期跑OWASP Dependency-Check或类似工具。做不到百分之百安全,但至少别当最容易被捏的那个软柿子。
友情链接