Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: minor edits but please review. I also added a line about replacing switch-case with enums for the CS (which is the correct approach).

...

Every Java application has a single instance of class Runtime that allows the application to interface with the environment in which the application is running. The current runtime can be obtained from the Runtime.getRuntime() method. The semantics of Runtime.exec are poorly defined, so it's best not to rely on its behavior any more than necessary. It will invoke the command directly without a shell. If you want a shell, you can use /bin/sh, -c on POSIX or cmd.exe on Windows. The variants of exec() that take the command line a single String split it with a StringTokenizer. On Windows, these tokens are concatenated back into a single argument string somewhere before being executed.

...

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

Code Block
bgColor#FFcccc
  
import java.io.InputStream;

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);
    }
  }
}

...

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 proc.

Code Block
bgColor#FFcccc
  
import java.io.InputStream;

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);
    }
  }
}

...

Code Block
bgColor#ccccff
// ...
String dir = null;

int number = Integer.parseInt(System.getproperty("dir")); // only allow integer choices
switch(number) {
  case 1: 
    dir = "data1"
    break; // Option 1
  case 2: 
    dir = "data2"
    break; // Option 2
  default: // invalid
    break; 
}
if (dir == null) {
  // handle error

}

This compliant solution hard codes the directories that may be listed.

This solution can quickly become unmanageable if you have many available directories. A more extensible solution is to read all the email addresses from a properties file into a java.util.Properties object or use an enum.

Compliant Solution (Avoid Runtime.exec())

...

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

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

...