文章目录

背景

代码漏洞扫描,发现 redisson 版本有漏洞

CVE:CVE-2023-42809
有问题的 jar 包:redisson-spring-boot-starter-3.17.3.jar

于是上网找漏洞解决方案,参考文档:https://nvd.nist.gov/vuln/detail/CVE-2023-42809

Redisson is a Java Redis client that uses the Netty framework. Prior to version 3.22.0, some of the messages received from the Redis server contain Java objects that the client deserializes without further validation. Attackers that manage to trick clients into communicating with a malicious server can include especially crafted objects in its responses that, once deserialized by the client, force it to execute arbitrary code. This can be abused to take control of the machine the client is running in. Version 3.22.0 contains a patch for this issue. Some post-fix advice is available. Do NOT use Kryo5Codec as deserialization codec, as it is still vulnerable to arbitrary object deserialization due to the setRegistrationRequired(false) call. On the contrary, KryoCodec is safe to use. The fix applied to SerializationCodec only consists of adding an optional allowlist of class names, even though making this behavior the default is recommended. When instantiating SerializationCodec please use the SerializationCodec(ClassLoader classLoader, Set<String> allowedClasses) constructor to restrict the allowed classes for deserialization.

简单来说就是 3.22.0 版本包含此问题的修补程序
于是升级依赖

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>${redisson.version}</version>
</dependency>

本地运行正常,结果到线上就报错了

Caused by: java.lang.ClassNotFoundException: org.springframework.data.redis.connection.zset.Tuple
at java.net.URLClassLoader.findClass(URLClassLoader.java:387)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
… 30 common frames omitted

好吧,开始排查
 

排查

方向1:线上环境和本地环境
线上用的 docker 是 open-jdk,本地用的是普通 jdk
于是下载了 open-jdk,测试发现没有问题,下载地址 :https://mirrors.tuna.tsinghua.edu.cn/Adoptium/

方向2:启动命令
线上启动命令和idea的启动命令不一样,逐个排除后,发现idea加了 -noverify
百度了一下 -noverify 的含义

-noverify 是 Java 虚拟机(JVM)的一个启动参数,用于禁用字节码验证。字节码验证是 JVM 在加载类的过程中执行的一个重要步骤,用于确保字节码的安全性和正确性。通过字节码验证,JVM可以检查字节码是否符合Java虚拟机规范,以避免潜在的安全漏洞和错误。
当使用 -noverify 参数启动 Java 应用程序时,JVM 将跳过字节码验证阶段,这可能会带来一些潜在的风险和副作用,包括但不限于:
1:由于跳过了字节码验证,恶意代码可能会更容易地被加载和执行,从而增加了安全漏洞的风险。
2:字节码验证是确保代码安全性和正确性的重要步骤,跳过这一步可能会导致潜在的运行时错误,从而影响应用程序的性能和稳定性。
3:某些应用程序可能依赖于字节码验证来确保代码的正确性,因此禁用字节码验证可能导致应用程序出现意外行为或错误。
通常情况下,不建议在生产环境中使用 -noverify 参数,除非您明确了解其潜在风险并且有充分的理由需要禁用字节码验证。在开发和调试过程中,有时会使用 -noverify 参数来加快启动时间,但在生产环境中应该避免使用。

简单来说就是线上不能用 -noverify,因为不安全

方向3:redission 和 springboot 的版本不兼容
问题根本原因就是这个

 

解决

可以看到 redisson-spring-boot-starter 版本 3.22.0 里面的 redisson-spring-data 是 redisson-spring-data-31

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-data-31</artifactId>
    <version>${project.version}</version>
</dependency>

但项目的 springboot 版本用的是 2.7.18,所以要使用 redisson-spring-data-27,参考文档:https://github.com/redisson/redisson/tree/master/redisson-spring-data

解决思路,排除 redisson-spring-data-31,引入 redisson-spring-data-27

解决后的依赖

<redisson.version>3.22.0</redisson.version>
     
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>${redisson.version}</version>

</dependency>

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-data-27</artifactId>
    <version>${redisson.version}</version>
</dependency>
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐