Sí, creo que hay formas "seguras".
También creo que, en relación con su pregunta, su objetivo puede ser evitar la inyección de comandos y / o no activar alertas en los escáneres de código fuente estático . El segundo podría ser complicado, ya que la gran cantidad de falsos positivos que generan estos escáneres.
Honestamente, creo que la primera alerta de "Firebug" podría ser, en la mayoría de los casos, un Falso Positivo (aunque es útil para el reconocimiento) de "Inyección de comandos" (si solo está llamando a un archivo ejecutable o de archivo), de hecho el la regla se debe aplicar justo cuando llama a un intérprete de bash / cmd / sh. Entonces, la vulnerabilidad podría ser posible al crear directamente en ella argumentos anidados de fuentes desconocidas.
Ejemplo de inyección de comandos (opciones tanto exec como ProcessBuilder):
String[] cmd = new String[]{"/bin/bash","-c","/usr/sbin/sendmail -f"+emailFrom};
Runtime.getRuntime().exec(cmd);
//Same as Exec
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.start();
Dado que Java realiza una bifurcación () del ejecutable en lugar de llamar directamente a un intérprete de comandos del sistema operativo (como proc_open / exec en PHP), podríamos decir que estas funciones están "por defecto" más protegidas contra la inyección de comandos.
Por otra parte, también deberías conocer los ataques "Inyección de argumentos" (se podría combatir como la Inyección de comandos en sí misma, pero ligeramente diferente). En cuyo caso, ProcessBuilder es la solución segura para ir con.
La razón es que exec () acepta una cadena y tokenize / interprete espacios para transformarla en una matriz de argumentos pero ProcessBuilder no, por lo que los espacios no se interpretan para la tokenización de cadenas !
Ejemplo de inyección de argumento:
}else if( ("Argument Injection".equals(submit)) ){
//We are invoking an process without calling a sh/bash/cmd interpreter. But Still, thanks to Runtime.java tokenizer, we are able to inject extra arguments to target process.
String cmd = "/usr/sbin/sendmail -f" + emailFrom;
Runtime.getRuntime().exec(cmd);
Posible carga útil:
[email protected] -be ${run{/usr/bin/wget${substr{10}{1}{$tod_log}}http://127.0.0.1/test}}
Ya que está un poco fuera de contexto para esta pregunta, dejo aquí una investigación que realicé sobre esos ataques. Estos temas podrían ser útiles para cualquier persona preocupada por la técnica de usar funciones predefinidas de Languages para llamar a ejecutables en sistemas de archivos.
Java CommandI / ArgumentI: enlace
PHP:
enlace
Ruby / Python / JS:
enlace
Proporciono varios PoC donde puedes jugar con los diferentes comandos y ver cuáles encajan en tus especificaciones más seguras para la ejecución del archivo de destino.