flawopen.com/Command Injection/Java Runtime.exec()
¿Runtime.exec() en Java evita Command Injection?
Runtime.exec(String) no ejecuta un shell de forma implícita, así que los operadores de shell no se interpretan automáticamente. Aun así, la cadena se divide en programa y argumentos, y el texto no confiable puede cambiar los argumentos que recibe el programa. ProcessBuilder hace explícitos los límites; valida cada valor y limita el ejecutable y las opciones permitidas.
// La entrada del usuario se concatena en la cadena de comando Runtime.getRuntime().exec( "approved-tool --input " + filename );
// Ejecutable fijo y argumentos separados; valida filename primero String safeName = validateFilename(filename); new ProcessBuilder( "/opt/app/bin/approved-tool", "--input", safeName ).start();
La inyección de shell y la inyección de argumentos son distintas
Desde Java 18, Oracle marca Runtime.exec(String) como obsoleto por ser propenso a errores y recomienda exec(String[]) o ProcessBuilder. El overload de cadena separa tokens por espacios en blanco, lo que puede dividir argumentos como rutas con espacios. Runtime.exec(String) no inicia implícitamente sh ni otro shell; Oracle documenta que el overload convierte la cadena en un array de argumentos. Esto evita que los metacaracteres habituales actúen como sintaxis del shell, pero no vuelve segura la entrada: la tokenización aún puede crear argumentos adicionales, y el programa puede interpretar un argumento como opción. ProcessBuilder recibe una lista de cadenas para el ejecutable y sus argumentos; en plataformas comunes, cada elemento define un límite. Mantén fijo el ejecutable, valida los valores según la gramática esperada por el programa y rechaza o trata los valores que parezcan opciones. Usa -- solo si la documentación del programa garantiza ese comportamiento. No invoques explícitamente un shell, como sh -c, con datos no confiables.
Preguntas frecuentes
No. Reduce el riesgo de inyección en el shell para ese overload, pero aún puede haber inyección de argumentos. El programa puede interpretar entradas del atacante como opciones o nombres de archivo. Usa ProcessBuilder con ejecutable fijo y argumentos separados, y valida cada valor según el programa.
No. Construye la lista de programa y argumentos e inicia el proceso; no comprueba si son seguros o válidos. Aplica listas permitidas y validación en la aplicación, y sigue las reglas de argumentos documentadas por el programa.