Command injection in org.apache.hadoop.fs.FileUtil.unTarUsingTar
Description
Apache Hadoop's FileUtil.unTar(File, File) API does not escape the input file name before being passed to the shell. An attacker can inject arbitrary commands. This is only used in Hadoop 3.3 InMemoryAliasMap.completeBootstrapTransfer, which is only ever run by a local user. It has been used in Hadoop 2.x for yarn localization, which does enable remote code execution. It is used in Apache Spark, from the SQL command ADD ARCHIVE. As the ADD ARCHIVE command adds new binaries to the classpath, being able to execute shell scripts does not confer new permissions to the caller. SPARK-38305. "Check existence of file before untarring/zipping", which is included in 3.3.0, 3.1.4, 3.2.2, prevents shell commands being executed, regardless of which version of the hadoop libraries are in use. Users should upgrade to Apache Hadoop 2.10.2, 3.2.4, 3.3.3 or upper (including HADOOP-18136).
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Apache Hadoop's FileUtil.unTar() API does not escape input file names before passing to the shell, allowing arbitrary command injection.
Vulnerability
Description
Apache Hadoop's FileUtil.unTar(File, File) API does not properly escape the input file name before passing it to a shell command. This flaw allows an attacker to inject arbitrary shell commands by crafting a malicious filename. The issue is present in the unTarUsingTar method, which constructs a shell command string without sanitizing the input filename [1][2].
Exploitation
Scenarios
The vulnerability is reachable through multiple paths depending on the Hadoop version. In Hadoop 3.3, it is used in the InMemoryAliasMap.completeBootstrapTransfer method, which is only executed by a local user. In Hadoop 2.x, it is used during YARN localization, enabling remote code execution when a remote user triggers the localization of a malicious archive. The flaw also affects Apache Spark's ADD ARCHIVE SQL command, though exploitation in Spark does not confer additional permissions since the archive is already being added to the classpath [1].
Impact
Successful exploitation allows an attacker to execute arbitrary shell commands with the privileges of the Hadoop or YARN process. In Hadoop 2.x YARN localization, a remote attacker can achieve remote code execution. For Hadoop 3.3, only local privilege escalation is possible through the InMemoryAliasMap path [1].
Mitigation
The vulnerability is fixed in Apache Hadoop 2.10.2, 3.2.4, and 3.3.3. The fix includes using FileUtil.makeSecureShellPath() to properly escape the input filename in the shell command [2]. Additionally, Apache Spark includes a check file existence before untarring (SPARK-38305), which mitigates the issue in Spark regardless of the Hadoop library version [1]. Users should upgrade to the patched Hadoop versions or apply the relevant patches.
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.hadoop:hadoop-commonMaven | >= 2.0.0, < 2.10.2 | 2.10.2 |
org.apache.hadoop:hadoop-commonMaven | >= 3.0.0-alpha, < 3.2.4 | 3.2.4 |
org.apache.hadoop:hadoop-commonMaven | >= 3.3.0, < 3.3.3 | 3.3.3 |
Affected products
2- Apache Software Foundation/Apache Hadoopv5Range: 2.0.0 to 2.10.1
Patches
1cae749b076f3HADOOP-18136. Verify FileUtils.unTar() handling of missing .tar files.
2 files changed · +43 −5
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java+10 −5 modified@@ -888,10 +888,13 @@ private static void unTarUsingTar(InputStream inputStream, File untarDir, private static void unTarUsingTar(File inFile, File untarDir, boolean gzipped) throws IOException { StringBuffer untarCommand = new StringBuffer(); + // not using canonical path here; this postpones relative path + // resolution until bash is executed. + final String source = "'" + FileUtil.makeSecureShellPath(inFile) + "'"; if (gzipped) { - untarCommand.append(" gzip -dc '") - .append(FileUtil.makeSecureShellPath(inFile)) - .append("' | ("); + untarCommand.append(" gzip -dc ") + .append(source) + .append(" | ("); } untarCommand.append("cd '") .append(FileUtil.makeSecureShellPath(untarDir)) @@ -901,15 +904,17 @@ private static void unTarUsingTar(File inFile, File untarDir, if (gzipped) { untarCommand.append(" -)"); } else { - untarCommand.append(FileUtil.makeSecureShellPath(inFile)); + untarCommand.append(source); } + LOG.debug("executing [{}]", untarCommand); String[] shellCmd = { "bash", "-c", untarCommand.toString() }; ShellCommandExecutor shexec = new ShellCommandExecutor(shellCmd); shexec.execute(); int exitcode = shexec.getExitCode(); if (exitcode != 0) { throw new IOException("Error untarring file " + inFile + - ". Tar process exited with exit code " + exitcode); + ". Tar process exited with exit code " + exitcode + + " from command " + untarCommand); } }
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileUtil.java+33 −0 modified@@ -17,6 +17,7 @@ */ package org.apache.hadoop.fs; +import static org.apache.hadoop.test.LambdaTestUtils.intercept; import static org.apache.hadoop.test.PlatformAssumptions.assumeNotWindows; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -1135,6 +1136,38 @@ public void testUntar() throws IOException { doUntarAndVerify(new File(tarFileName), untarDir); } + /** + * Verify we can't unTar a file which isn't there. + * This will test different codepaths on Windows from unix, + * but both MUST throw an IOE of some kind. + */ + @Test(timeout = 30000) + public void testUntarMissingFile() throws Throwable { + File dataDir = GenericTestUtils.getTestDir(); + File tarFile = new File(dataDir, "missing; true"); + File untarDir = new File(dataDir, "untarDir"); + intercept(IOException.class, () -> + FileUtil.unTar(tarFile, untarDir)); + } + + /** + * Verify we can't unTar a file which isn't there + * through the java untar code. + * This is how {@code FileUtil.unTar(File, File} + * will behave on Windows, + */ + @Test(timeout = 30000) + public void testUntarMissingFileThroughJava() throws Throwable { + File dataDir = GenericTestUtils.getTestDir(); + File tarFile = new File(dataDir, "missing; true"); + File untarDir = new File(dataDir, "untarDir"); + // java8 on unix throws java.nio.file.NoSuchFileException here; + // leaving as an IOE intercept in case windows throws something + // else. + intercept(IOException.class, () -> + FileUtil.unTarUsingJava(tarFile, untarDir, false)); + } + @Test (timeout = 30000) public void testCreateJarWithClassPath() throws Exception { // create files expected to match a wildcard
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-8wm5-8h9c-47pcghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-25168ghsaADVISORY
- github.com/apache/hadoop/commit/cae749b076f35f0be13a926ee8cfbb7ce4402746ghsaWEB
- lists.apache.org/thread/mxqnb39jfrwgs3j6phwvlrfq4mlox130ghsax_refsource_MISCWEB
- security.netapp.com/advisory/ntap-20220915-0007ghsaWEB
- security.netapp.com/advisory/ntap-20220915-0007/mitrex_refsource_CONFIRM
News mentions
0No linked articles in our index yet.