Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

External programs are commonly invoked to perform a function required by the overall system. This practice is a form of reuse and might even be considered a crude form of component-based software engineering. Command and argument injection vulnerabilities occur when an application fails to sanitize untrusted input and uses it in the execution of external programs.

...

This noncompliant code example provides a directory listing using the dir command. It is implemented using Runtime.exec() to invoke the Windows dir command.

Code Block
bgColor#FFcccc
  
class DirList {
  public static void main(String[] args) throws Exception {
    String dir = System.getProperty("dir");
    Runtime rt = Runtime.getRuntime();
    Process proc = rt.exec("cmd.exe /C dir " + dir);
    int result = proc.waitFor();
    if (result != 0) {
      System.out.println("process error: " + result);
    }
    InputStream in = (result == 0) ? proc.getInputStream() :
                                     proc.getErrorStream();
    int c;
    while ((c = in.read()) != -1) {
      System.out.print((char) c);
    }
  }
}

Because Runtime.exec() receives unsanitized data originating from the environment, this code is susceptible to a command injection attack.

An attacker can exploit this program using the following command:

...

which first attempts to list a nonexistent dummy folder , and then prints bad to the console.

...

This noncompliant code example provides the same functionality but uses the POSIX ls command. The only difference from the Windows version is the argument passed to Runtime.exec().

Code Block
bgColor#FFcccc
  
class DirList {
  public static void main(String[] args) throws Exception {
    String dir = System.getProperty("dir");
    Runtime rt = Runtime.getRuntime();
    Process proc = rt.exec(new String[] {"sh", "-c", "ls " + dir});
    int result = proc.waitFor();
    if (result != 0) {
      System.out.println("process error: " + result);
    }
    InputStream in = (result == 0) ? proc.getInputStream() :
                                     proc.getErrorStream();
    int c;
    while ((c = in.read()) != -1) {
      System.out.print((char) c);
    }
  }
}

...

Compliant Solution (Sanitization)

This compliant solution solution sanitizes the untrusted user input by permitting only a small group of whitelisted characters in the argument that will be passed to Runtime.exec(); all other characters are excluded.

...

Code Block
bgColor#ccccff
import java.io.File;

class DirList {
  public static void main(String[] args) throws Exception {
    File dir = new File(System.getProperty("dir"));
    if (!dir.isDirectory()) {
      System.out.println("Not a directory");
    } else {
      for (String file : dir.list()) {
        System.out.println(file);
      }
    }
  }
}

Risk Assessment

Passing untrusted, unsanitized data to the Runtime.exec() method can result in command and argument injection attacks.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

IDS07-J

High

Probable

Medium

P12

L1

Automated Detection

ToolVersionCheckerDescription
The Checker Framework

Include Page
The Checker Framework_V
The Checker Framework_V

Tainting CheckerTrust and security errors (see Chapter 8)
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

JAVA.IO.INJ.COMMAND

Command Injection (Java)

Coverity7.5OS_CMD_INJECTIONImplemented
Parasoft Jtest
Include Page
Parasoft_V
Parasoft_V
CERT.IDS07.EXECDo not use 'Runtime.exec()'
SonarQube
Include Page
SonarQube_V
SonarQube_V

S2076

OS commands should not be vulnerable to injection attacks

Related Vulnerabilities

Related Guidelines

Android Implementation Details

Runtime.exec() can be called from Android apps to execute operating system commands.

Bibliography

...


...

             Image Modified