1

I need to call a Unix script in my Java code, wait for it to execute, and get the output. The script will do a 'find', and user will provide the directory he wants the 'find' to look in

String[] cmd = new String[] { "/bin/sh", "-c",
                              runnerScript.getAbsolutePath() + " " + Param1 };
Process p = Runtime.getRuntime().exec(cmd);

Problem is : How can I prevent one to type ' && rm -rf *' or ' / -exec rm..' ?

I have an idea like check if the directory exist on the server, or use a method like isLetterOrDigit(), but I want to know if a safer way exists. I know for Sql Query I can use PreparedStatement to work around this problem. Is there something similar when calling a script?

khelwood
  • 55,782
  • 14
  • 81
  • 108

2 Answers2

1

If your script is executable, I believe you should be able to construct your command like this:

String[] cmd = new String[] { runnerScript.getAbsolutePath(), Param1 };

This way, you are calling your script, and just passing it the parameter; rather than calling bash -c and passing it a string to execute, which is inherently unsafe.

To specify which shell your script should run in, you can put #!/bin/sh at the top of the script.

khelwood
  • 55,782
  • 14
  • 81
  • 108
0

Refer to ProcessBuilder for a similar purpose.

Refer to : How to sanitize user input used in Runtime.exec()?

ProcessBuilder pb = new ProcessBuilder("ls", "-l");
try {
    Process p = pb.start();
    System.out.println("Executed");
    while (p.isAlive())
    {}
    InputStream s = p.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(s));
    StringBuilder builder = new StringBuilder();
    String line = null;
    while ( (line = reader.readLine()) != null) {
       builder.append(line);
       builder.append(System.getProperty("line.separator"));
    }
    String result = builder.toString();
    System.out.println(result);
} catch (IOException e) {
    e.printStackTrace();
}
Speeeddy
  • 154
  • 8