【问题标题】:How can I find out what version of Log4J I am using?如何找出我正在使用的 Log4J 版本?
【发布时间】:2016-09-23 03:32:13
【问题描述】:

众所周知,至少有四个或五个 Log4j JAR 文件最终位于类路径中。如何判断我使用的是哪个版本?

【问题讨论】:

    标签: java log4j


    【解决方案1】:

    删除所有不需要的版本的 JAR 文件(一个就足够了)并找出剩下的版本,查看文件名。

    例如:

    log4j-1.2.17.jar
    

    【讨论】:

      【解决方案2】:

      这取决于 ClassLoader,但看看the example

      import org.apache.log4j.Layout;
      
      public class X {
          public static void main(String[] a) {
              Package p = Layout.class.getPackage();
              System.out.println(p);
              System.out.println("Implementation title:   " + p.getImplementationTitle());
              System.out.println("Implementation vendor:  " + p.getImplementationVendor());
              System.out.println("Implementation version: " + p.getImplementationVersion());
          }
      }
      

      你可以在log4j的Layout类上调用getImplementationVersion方法:

      org.apache.log4j.Layout.class.getPackage().getImplementationVersion()
      

      【讨论】:

      • 很好的答案,也许是正确的,但我得到了那个类的所有空值。您提供的文档说它适用于 1.2 和 1.3。这可能意味着我使用的是版本 2。
      • 我下载了更新版本的 Log4j (2.13.1) 并发现 getImplementationVersiongetSpecificationVersion 方法可以使用它。对于旧版本,请参阅my answer below
      • 答案中给出的链接已损坏。有人可以分享示例代码以编程方式打印 log4j 版本吗?。
      【解决方案3】:

      一个简单的方法:

      1. 在 log.debug() 处设置调试断点
      2. 进入下一条语句以确定被调用的类。
      3. 检查被调用类的 JAR 版本。

      【讨论】:

        【解决方案4】:

        我不认为这是首选方法,但这是我确定我的软件使用的 Log4j 版本的方式:

        使用 .zip 归档实用程序打开或提取 Log4j .jar 的内容(Windows Explorer 支持这一点)。导航到“META-INF”子目录并在文本编辑器中打开文件“MANIFEST.MF”。找到以“Implementation-Version”开头的那一行,这是Log4j版本。

        显然,这不是程序化解决方案。但是,如果您只是想知道您使用的是什么版本并且您拥有 .jar 存档,那么它可以工作。

        我注意到Package.getSpecificationVersion()Package.getImplementationVersion()(如Loic M.'s answer 中所述)适用于其他.jar 库,但不适用于我的Log4j。可能是我使用的版本不支持。

        我下载了2.13.1 版本来尝试上面提到的方法,发现他们确实可以使用它。所以是我的版本(1.2.16)不支持它们并返回null

        【讨论】:

          【解决方案5】:

          我在得知我的服务器可能容易受到新的 Log4j 漏洞利用 (CVE-2021-44228) 后来到这里。所以我需要知道我是否安装了过时/易受攻击的 Log4j 版本 2。

          此处的先前答案无助于检测旧版本,因为它们是为了让已经运行的 Java 代码找出该代码使用的 Log4j 版本,而我需要知道是否有 any Java 应用程序可能正在使用易受攻击的版本。

          这就是我所做的:

          sudo find / -name 'log4j*'
          

          这列出了我 (Linux) 服务器上所有与 Log4j 相关的文件。这向我展示了几个 1.x 版本,它们不易受到此特定 CVE 的攻击,还有一个 2.15.0 文件,其中已经包含 CVE 的修复程序。

          如果您运行此程序并找到具有 2.x 的文件或文件夹名称,其中 x

          注意

          我被警告说这不足以满足我的目的,因为 Log4j 文件可能隐藏在 .jar 文件中,find 命令不会发现该文件。

          更新

          这是一个尝试扫描所有 .jar 文件的公共项目,以便在存档中也找到 Log4j 代码:Log4-detector

          【讨论】:

          • 要列出系统上所有包含易受攻击的类文件的 JAR 文件(即使在胖 JAR 中),您可以使用:for f in $(find / -name '*.jar' 2>/dev/null); do echo "Checking $f..."; unzip -l "$f" | grep -F org/apache/logging/log4j/core/lookup/JndiLookup.class; done
          • 请注意,Log4j v1 也可能受到影响:nvd.nist.gov/vuln/detail/CVE-2019-17571
          • Log4j 1.x 还有其他漏洞。 stackoverflow.com/a/70405229/1329426.
          【解决方案6】:

          查看 core.jar -> log4j-core .zip\META-INF\maven\org.apache.logging.log4j\log4j-core\pom 文件显示版本

          【讨论】:

            【解决方案7】:

            我编写了一个小的 Bash 脚本来检查位于该服务器上的每个 Log4j JAR 文件的版本。它从清单文件中读取版本信息,因为信任文件名有点冒险。

            locs=( $(sudo find / -name 'log4j*'|grep jar) )
            fcount=${#locs[@]}
            
            echo "Found $fcount jar files"
            echo " "
            
            for (( j=0; j<${fcount}; j++ ));
            do
                unzip ${locs[$j]} META-INF/MANIFEST.MF
                mv META-INF/MANIFEST.MF META-INF/MANIFEST$j.MF
            done
            
            echo " "
            for (( j=0; j<${fcount}; j++ ));
            do
                echo ${locs[$j]}
                tail -2 META-INF/MANIFEST$j.MF
            done
            

            【讨论】:

            • 可能运行shellcheck.net 并修复它报告的各种问题。只需在 find 输出到达时对其进行循环,就可以避免数组出现的多个问题。简而言之,sudo find / -name 'log4j*.jar' -exec sh -c '... your loop code here ...' _ {} +
            【解决方案8】:
            1. 因为来自不同 Log4j 依赖项的相同类有多个版本,所以它们中的任何一个都可能在运行时加载(假设相同的类名存在于不同的 JAR 文件中)。

            2. 我使用EclipseIntelliJ IDEA 提供的插件来查看Maven 依赖树。然后我排除旧版本,只使用所需的 Log4j 版本。

            【讨论】:

              【解决方案9】:

              牢记 Log4j 2 安全漏洞 CVE-2021-45105: 在 Linux 和 macOS 上,您可以使用 Syft 生成软件材料清单 (SBOM),并使用 Grype 扫描漏洞。结合使用,您可以找到存在风险的 Log4j 版本,您拥有哪些版本并获得有关漏洞的报告。

              Apache 建议放弃 Log4j 1,至少使用他们的'bridge',log4j-1.2-api,从包含 1.x 调用的应用程序中调用 Log4j 2。

              【讨论】:

                【解决方案10】:

                Java 运行时了解 Log4j 版本:

                LOGGER.info("Log4j version: " + org.apache.logging.log4j.util.PropertiesUtil.class.getPackage().getImplementationVersion());
                

                或者

                System.out.println("Log4j version: " + org.apache.logging.log4j.util.PropertiesUtil.class.getPackage().getImplementationVersion());
                

                【讨论】:

                  猜你喜欢
                  • 2014-12-12
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-04-15
                  • 1970-01-01
                  • 2013-12-03
                  相关资源
                  最近更新 更多