VYPR
Critical severityNVD Advisory· Published Aug 4, 2022· Updated Aug 3, 2024

Command injection in org.apache.hadoop.fs.FileUtil.unTarUsingTar

CVE-2022-25168

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.

PackageAffected versionsPatched versions
org.apache.hadoop:hadoop-commonMaven
>= 2.0.0, < 2.10.22.10.2
org.apache.hadoop:hadoop-commonMaven
>= 3.0.0-alpha, < 3.2.43.2.4
org.apache.hadoop:hadoop-commonMaven
>= 3.3.0, < 3.3.33.3.3

Affected products

2

Patches

1
cae749b076f3

HADOOP-18136. Verify FileUtils.unTar() handling of missing .tar files.

https://github.com/apache/hadoopSteve LoughranFeb 21, 2022via ghsa
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

News mentions

0

No linked articles in our index yet.