如何找出我正在使用的 Log4J 版本?
Posted
技术标签:
【中文标题】如何找出我正在使用的 Log4J 版本?【英文标题】:How can I find out what version of Log4J I am using? 【发布时间】:2016-09-23 03:32:13 【问题描述】:众所周知,至少有四个或五个 Log4j JAR 文件最终位于类路径中。如何判断我使用的是哪个版本?
【问题讨论】:
【参考方案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) 并发现getImplementationVersion
和 getSpecificationVersion
方法可以使用它。对于旧版本,请参阅my answer below。
答案中给出的链接已损坏。有人可以分享示例代码以编程方式打印 log4j 版本吗?。【参考方案3】:
一个简单的方法:
-
在 log.debug() 处设置调试断点
进入下一条语句以确定被调用的类。
检查被调用类的 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 还有其他漏洞。 ***.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】:
因为来自不同 Log4j 依赖项的相同类有多个版本,所以它们中的任何一个都可能在运行时加载(假设相同的类名存在于不同的 JAR 文件中)。
我使用Eclipse 和IntelliJ 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());
【讨论】:
以上是关于如何找出我正在使用的 Log4J 版本?的主要内容,如果未能解决你的问题,请参考以下文章
如何找出我的 WebLogic 正在使用的 Mojarra 的当前版本?
Log4j 1:如何在不将版本更新到 2.15.0 的情况下缓解 log4j 中的漏洞
我如何找出Wildfly 1x.x.x中使用的RESTEasy版本