Versions Compared

Key

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

...

Code Block
bgColor#FFcccc
public class execExec {
  public static void main(String args[]) {
    try {
      Runtime rt = Runtime.getRuntime();
      Process proc = rt.exec("notemaker");
      int exitVal = proc.exitValue();
    } catch (Throwable t) { t.printStackTrace();}
  }
}

...

Code Block
bgColor#FFcccc
public class execExec {
  public static void main(String args[]) {
    try {
      Runtime rt = Runtime.getRuntime();
      Process proc = rt.exec("notemaker");
      int exitVal = proc.waitFor();
    } catch (Throwable t) { t.printStackTrace();}
  }
}

...

Code Block
bgColor#ccccff
public class execExec {
  public static void main(String args[]) {
    try {
      Runtime rt = Runtime.getRuntime();
      Process proc = rt.exec("notemaker");
      InputStream stderr = proc.getErrorStream();
      InputStreamReader isr = new InputStreamReader(stderr);
      BufferedReader br = new BufferedReader(isr);

      while ( (line = br.readLine()) != null)   
        System.out.println(line);  //prints the error lines

      int exitVal = proc.waitFor();
    } catch (Throwable t) { t.printStackTrace(); }
  }
}

The second compliant solution spawns a command interpreter and executes the user supplied command. It uses a separate OutputStream to write the output that is read in from the external process. More Java Pitfalls, Pitfall 1 and Javaworld article

Code Block
bgColor#ccccff
class execExec extends Thread  {
  InputStream is;
  String type;
  OutputStream os;

  execExec(InputStream is, String type) {
    this(is, type, null);
  }

  execExec(InputStream is, String type, OutputStream redirect) {
    this.is = is;
    this.type = type;
    this.os = redirect;
  }

  public void run() {
    try {
      PrintWriter pw = null;
      if (os != null) {
        pw = new PrintWriter(os);
      }  
     
      InputStreamReader isr = new InputStreamReader(is);
      BufferedReader br = new BufferedReader(isr);
      String line=null;
 
       while ( (line = br.readLine()) != null) {
         if (pw != null) {
           pw.println(line);
           pw.flush();
         }
 
         System.out.println(type + ">" + line);
       }
 
       if (pw != null)
         pw.flush();
    } catch (IOException ioe) { ioe.printStackTrace(); }
  }
}
	
public class execMeExecMe {
  public static void main(String[] args)
  {
    // ... perform command argument check  ...
	
    try {
	  FileOutputStream fos = new FileOutputStream("c:\\output.txt");
	  Runtime rt = Runtime.getRuntime();
	  Process proc = rt.exec("notemaker");
	  // any error message?
	  execExec errorGobbler = new execExec(proc.getErrorStream(), "ERROR");
	
	  // any output?
	  execExec outputGobbler = new execExec(proc.getInputStream(), "OUTPUT", fos);
	
	  errorGobbler.start();
	  outputGobbler.start();
	
	  // any error?
	  int exitVal = proc.waitFor();
	  errorGobbler.join();     //handle condition where the
          outputGobbler.join();    //process ends before the threads finish 

	  fos.flush();
	  fos.close();
    } catch (Throwable t) { t.printStackTrace(); }
  }
}

Risk Assessment

TODOMisusing exec() can seriously compromise the security of a Java application.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FIO02-J

?? high ??

probable

?? high

P??

L??

Automated Detection

...

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

Wiki Markup
\[[Daconta 00|AA. Java References#Daconta 00]\]
\[[Daconta 03|AA. Java References#Daconta 03]\] Pitfall 1
\[[API 06|AA. Java References#API 06]\] [exec()|
Javaworld article
http://
www
java.
javaworld
sun.com/
javaworld/jw-12-2000/jw-1229-traps.html?Image Removed
More Java Pitfalls, Pitfall 1
Sun Java Documentation
javase/6/docs/api/java/lang/Runtime.html#exec(java.lang.String)]