代码之家  ›  专栏  ›  技术社区  ›  Igor Artamonov

不应用渐变依赖约束

  •  0
  • Igor Artamonov  · 技术社区  · 4 年前

    我的Gradle配置中有以下内容:

    dependencies {    
        implementation "org.slf4j:slf4j-api:1.7.32"
        implementation "org.apache.logging.log4j:log4j-slf4j-impl:2.15.0"
        implementation "org.slf4j:jul-to-slf4j:1.7.32"
        implementation "org.slf4j:jcl-over-slf4j:1.7.32"
    
        constraints {
            add("implementation", "org.apache.logging.log4j:log4j-core") {
                version {
                    strictly("[2.15")
                    prefer("2.15.0")
                }
                because("CVE-2021-44228 Log4j 2 Vulnerability")
            }
            add("implementation", "org.apache.logging.log4j:log4j-api") {
                version {
                    strictly("[2.15")
                    prefer("2.15.0")
                }
                because("CVE-2021-44228 Log4j 2 Vulnerability")
            }
        }
    }
    

    虽然这个配置不直接依赖于log4j,但它对log4j有一些暂时的依赖。我预计它将强制使用2.15.0或更高版本。

    但不幸的是,这并没有改变任何事情:

    $ gradle dependencies | grep log4j
    +--- org.apache.logging.log4j:log4j-slf4j-impl:2.15.0
    |    \--- org.apache.logging.log4j:log4j-api:2.15.0 -> 2.13.3
    .....
    +--- org.apache.logging.log4j:log4j-api:{strictly [2.15; prefer 2.15.0} -> 2.13.3 (c)
    \--- org.apache.logging.log4j:log4j-core:{strictly [2.15; prefer 2.15.0} -> 2.13.3 (c)
    

    $ gradle dependencyInsight --dependency org.apache.logging.log4j
    
    > Task :dependencyInsight 
    org.apache.logging.log4j:log4j-api:2.13.3
    variant "compile" [
      org.gradle.status                  = release (not requested)
      org.gradle.usage                   = java-api
      org.gradle.libraryelements         = jar (compatible with: classes+resources)
      org.gradle.category                = library
    
      Requested attributes not found in the selected variant:
         org.gradle.dependency.bundling     = external
         org.gradle.jvm.environment         = standard-jvm
         org.jetbrains.kotlin.platform.type = jvm
         org.gradle.jvm.version             = 13
    ]
    Selection reasons:
      - Selected by rule
      - By constraint : CVE-2021-44228 Log4j 2 Vulnerability
    
    org.apache.logging.log4j:log4j-api:{strictly [2.15; prefer 2.15.0} -> 2.13.3
    \--- compileClasspath
    
    org.apache.logging.log4j:log4j-api:2.15.0 -> 2.13.3
    \--- org.apache.logging.log4j:log4j-slf4j-impl:2.15.0
         \--- compileClasspath 
    

    为什么会降级到2.13.3版?尽管它被设定为2.15 log4j-slf4j-impl 而且也是约束所要求的。

    Gradle 6.9和7.2的结果相同

    --

    Upd:

    为了简单起见,我将约束更改为:

        add("implementation", "org.apache.logging.log4j:log4j-core:2.15.0") {
            because("CVE-2021-44228 Log4j 2 Vulnerability")
        }
        add("implementation", "org.apache.logging.log4j:log4j-api:2.15.0") {
            because("CVE-2021-44228 Log4j 2 Vulnerability")
        }
    

    仍然没有效果

    0 回复  |  直到 4 年前
        1
  •  1
  •   Igor Artamonov    4 年前

    这个问题是由 io.spring.dependency-management Gradle插件,也用于该项目。删除插件修复了这个问题。

    所以解决办法是移除 伊奥。春天依赖关系管理 插件。

    还有,正确的约束 必须是 以下内容:

    constraints {
        add("implementation", "org.apache.logging.log4j:log4j-core") {
            version {
                strictly("[2.15,3[")
                prefer("2.15.0")
            }
            because("CVE-2021-44228 Log4j 2 Vulnerability")
        }
    }
    

    也就是说,只是 log4j-core 足够了,版本范围必须精确到 [2.15,3[

        2
  •  0
  •   Martin Zeitler    4 年前

    library 取决于 org.slf4j:slf4j-api:1.7.25 .

    dependencies {    
        testIplementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.15.0'
    }
    

    可能没有必要这样做 constraints ; 尝试 mavenCentral() ? 正如大家所看到的(上面的链接),它与编译、运行时和测试相关。当Maven Central建议 testImplementation ,这可能是要使用的正确配置。

        3
  •  0
  •   Scott    4 年前

    格拉德尔队 published a workaround 特别针对2.15.0之前版本中的关键Log4J错误。然而,据报道,一个新的漏洞促使2.16.0发布,因此您应该相应地更新规则。

    然而,如果您使用的是Spring的依赖管理插件,Gradle推荐的修复方案就不起作用 id("io.spring.dependency-management") version "x.y.z" .

    要处理Gradle依赖项和Spring依赖项管理,只需创建一个为Log4J设置版本要求的插件:

    object Log4jConvention : ServiceConvention {
        private val log = KotlinLogging.logger { }
        private val dependencies = listOf(
            "org.apache.logging.log4j:log4j-core",
            "org.apache.logging.log4j:log4j-slf4j-impl",
            "org.apache.logging.log4j:log4j-jul"
        )
    
        override fun apply(project: Project) {
            project.dependencies.constraints { constraints ->
                listOf("compileClasspath", "implementation", "runtimeOnly", "runtimeClasspath").forEach { configuration ->
                    dependencies.forEach { dependency ->
                        constraints.add(configuration, dependency) { c ->
                            c.version { v ->
                                v.strictly("[2.16, 3[")
                                v.require("2.16.0")
                                v.reject("[2.0, 2.16[")
                            }
                            c.because("CVE-2021-44228: Log4j vulnerable to remote code execution")
                            log.info { "Applied log4j version constraint to $dependency for configuration $configuration" }
                        }
                    }
                }
            }
            log.info { "Applied log4j version constraints" }
        }
    }
    

    要处理Spring启动依赖关系管理:

    object SpringBootLog4jConvention : ServiceConvention {
        private val log = KotlinLogging.logger { }
    
        override fun apply(project: Project) {
            project.plugins.findPlugin("io.spring.dependency-management") ?: return
            project.configurations.all {
                it.resolutionStrategy.eachDependency { details ->
                    if (details.requested.group == "org.apache.logging.log4j") {
                        details.useVersion("2.16.+")
                    }
                }
            }
            log.info { "Applied fixed Log4J resolution to Spring dependency management" }
        }
    }
    
    
    推荐文章