CVE-2022-25914: Insufficient Information (NVD-CWE-noinfo)
value: The package com.google.cloud.tools:jib-core before 0.22.0 are vulnerable to Remote Code Execution (RCE) via the isDockerInstalled function, due to attempting to execute input.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
CVSS v3 base score: 9.8
Published: 2022-09-08T05:15Z
Repository: https://github.com/GoogleContainerTools/jib
Language: Markdown
Files changed: jib-core/src/main/java/com/google/cloud/tools/jib/docker/CliDockerClient.java, jib-core/src/test/java/com/google/cloud/tools/jib/docker/CliDockerClientTest.java, jib-gradle-plugin/README.md, jib-maven-plugin/README.md
Commit date: 2022-08-25 16:23:29 -0400
Commit message: Check if file exists when executable path is passed in through jib dockerClient.executable (#3744)

* Check if file exists when executable path is passed in through jib.dockerClient.executable
Diff: diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/docker/CliDockerClient.java b/jib-core/src/main/java/com/google/cloud/tools/jib/docker/CliDockerClient.java
index c62ff819..7c9c23cd 100644
--- a/jib-core/src/main/java/com/google/cloud/tools/jib/docker/CliDockerClient.java
+++ b/jib-core/src/main/java/com/google/cloud/tools/jib/docker/CliDockerClient.java
@@ -101,34 +101,32 @@ public class CliDockerClient implements DockerClient {
 
   /** Default path to the docker executable. */
   public static final Path DEFAULT_DOCKER_CLIENT = Paths.get("docker");
 
   /**
-   * Checks if Docker is installed on the user's system and accessible by running the default {@code
-   * docker} command.
+   * Checks if Docker is installed on the user's system by running the `docker` command.
    *
    * @return {@code true} if Docker is installed on the user's system and accessible
    */
   public static boolean isDefaultDockerInstalled() {
-    return isDockerInstalled(DEFAULT_DOCKER_CLIENT);
+    try {
+      new ProcessBuilder(DEFAULT_DOCKER_CLIENT.toString()).start();
+      return true;
+    } catch (IOException ex) {
+      return false;
+    }
   }
 
   /**
-   * Checks if Docker is installed on the user's system and accessible by running the given {@code
-   * docker} executable.
+   * Checks if Docker is installed on the user's system and by verifying if the executable path
+   * provided has the appropriate permissions.
    *
    * @param dockerExecutable path to the executable to test running
    * @return {@code true} if Docker is installed on the user's system and accessible
    */
   public static boolean isDockerInstalled(Path dockerExecutable) {
-    try {
-      new ProcessBuilder(dockerExecutable.toString()).start();
-      return true;
-
-    } catch (IOException ex) {
-      return false;
-    }
+    return Files.exists(dockerExecutable);
   }
 
   /**
    * Gets a function that takes a {@code docker} subcommand and gives back a {@link ProcessBuilder}
    * for that {@code docker} command.
diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/docker/CliDockerClientTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/docker/CliDockerClientTest.java
index 4d1f37f6..3e7cca5b 100644
--- a/jib-core/src/test/java/com/google/cloud/tools/jib/docker/CliDockerClientTest.java
+++ b/jib-core/src/test/java/com/google/cloud/tools/jib/docker/CliDockerClientTest.java
@@ -22,15 +22,17 @@ import com.google.cloud.tools.jib.api.ImageReference;
 import com.google.cloud.tools.jib.docker.CliDockerClient.DockerImageDetails;
 import com.google.cloud.tools.jib.image.ImageTarball;
 import com.google.cloud.tools.jib.json.JsonTemplateMapper;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.io.ByteStreams;
+import com.google.common.io.Resources;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.net.URISyntaxException;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Paths;
 import java.security.DigestException;
 import java.util.Arrays;
 import java.util.Collections;
@@ -72,10 +74,17 @@ public class CliDockerClientTest {
   @Test
   public void testIsDockerInstalled_fail() {
     Assert.assertFalse(CliDockerClient.isDockerInstalled(Paths.get("path/to/nonexistent/file")));
   }
 
+  @Test
+  public void testIsDockerInstalled_pass() throws URISyntaxException {
+    Assert.assertTrue(
+        CliDockerClient.isDockerInstalled(
+            Paths.get(Resources.getResource("core/docker/emptyFile").toURI())));
+  }
+
   @Test
   public void testLoad() throws IOException, InterruptedException {
     DockerClient testDockerClient =
         new CliDockerClient(
             subcommand -> {
diff --git a/jib-core/src/test/resources/core/docker/emptyFile b/jib-core/src/test/resources/core/docker/emptyFile
new file mode 100644
index 00000000..e69de29b
diff --git a/jib-gradle-plugin/README.md b/jib-gradle-plugin/README.md
index 452d5ea0..5a130b72 100644
--- a/jib-gradle-plugin/README.md
+++ b/jib-gradle-plugin/README.md
@@ -288,11 +288,11 @@ Property | Type | Default | Description
 
 <a name="dockerclient-closure"></a>`dockerClient` is an object used to configure Docker when building to/from the Docker daemon. It has the following properties:
 
 Property | Type | Default | Description
 --- | --- | --- | ---
-`executable` | `File` | `docker` | Sets the path to the Docker executable that is called to load the image into the Docker daemon.
+`executable` | `File` | `docker` | Sets the path to the Docker executable that is called to load the image into the Docker daemon. **Please note**: Users are responsible for ensuring that the Docker path passed in is valid and has the right permissions to be executed.
 `environment` | `Map<String, String>` | *None* | Sets environment variables used by the Docker executable.
 
 #### System Properties
 
 Each of these parameters is configurable via commandline using system properties. Jib's system properties follow the same naming convention as the configuration parameters, with each level separated by dots (i.e. `-Djib.parameterName[.nestedParameter.[...]]=value`). Some examples are below:
diff --git a/jib-maven-plugin/README.md b/jib-maven-plugin/README.md
index 37dc8aca..b62c1b32 100644
--- a/jib-maven-plugin/README.md
+++ b/jib-maven-plugin/README.md
@@ -339,11 +339,11 @@ Property | Type | Default | Description
 
 <a name="dockerclient-object"></a>`dockerClient` is an object used to configure Docker when building to/from the Docker daemon. It has the following properties:
 
 Property | Type | Default | Description
 --- | --- | --- | ---
-`executable` | string | `docker` | Sets the path to the Docker executable that is called to load the image into the Docker daemon.
+`executable` | string | `docker` | Sets the path to the Docker executable that is called to load the image into the Docker daemon. **Please note**: Users are responsible for ensuring that the Docker path passed in is valid and has the right permissions to be executed.
 `environment` | map | *None* | Sets environment variables used by the Docker executable.
 
 #### System Properties
 
 Each of these parameters is configurable via commandline using system properties. Jib's system properties follow the same naming convention as the configuration parameters, with each level separated by dots (i.e. `-Djib.parameterName[.nestedParameter.[...]]=value`). Some examples are below:

Vulnerable code:    * Checks if Docker is installed on the user's system and accessible by running the default {@code
   * docker} command.
    return isDockerInstalled(DEFAULT_DOCKER_CLIENT);
   * Checks if Docker is installed on the user's system and accessible by running the given {@code
   * docker} executable.
    try {
      new ProcessBuilder(dockerExecutable.toString()).start();
      return true;

    } catch (IOException ex) {
      return false;
    }
`executable` | `File` | `docker` | Sets the path to the Docker executable that is called to load the image into the Docker daemon.
`executable` | string | `docker` | Sets the path to the Docker executable that is called to load the image into the Docker daemon.
Fixed code:    * Checks if Docker is installed on the user's system by running the `docker` command.
    try {
      new ProcessBuilder(DEFAULT_DOCKER_CLIENT.toString()).start();
      return true;
    } catch (IOException ex) {
      return false;
    }
   * Checks if Docker is installed on the user's system and by verifying if the executable path
   * provided has the appropriate permissions.
    return Files.exists(dockerExecutable);
import com.google.common.io.Resources;
import java.net.URISyntaxException;
  @Test
  public void testIsDockerInstalled_pass() throws URISyntaxException {
    Assert.assertTrue(
        CliDockerClient.isDockerInstalled(
            Paths.get(Resources.getResource("core/docker/emptyFile").toURI())));
  }

`executable` | `File` | `docker` | Sets the path to the Docker executable that is called to load the image into the Docker daemon. **Please note**: Users are responsible for ensuring that the Docker path passed in is valid and has the right permissions to be executed.
`executable` | string | `docker` | Sets the path to the Docker executable that is called to load the image into the Docker daemon. **Please note**: Users are responsible for ensuring that the Docker path passed in is valid and has the right permissions to be executed.