Sì, penso che esistano modi "sicuri".
Penso anche in relazione alla tua domanda che il tuo obiettivo può essere sia che evitare Command Injection e / o non attivare avvisi in scanner di codice sorgente statici ? Il secondo potrebbe essere complicato, dato l'alto numero di falsi positivi che questi scanner generano.
Onestamente penso che il primo avviso di "Firebug" potrebbe essere nella maggior parte dei casi un falso positivo (anche se utile per consapevolezza) per "Iniezione di comando" (se stai solo chiamando un particolare file eseguibile o bat), infatti la regola dovrebbe essere applicata solo quando si chiama un interprete bash / cmd / sh. Quindi, la vulnerabilità potrebbe essere possibile quando si crea direttamente in esso argomenti nidificati da fonti sconosciute.
Esempio di comando Injection (entrambe le opzioni exec e 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();
Dato che Java esegue un fork () dell'eseguibile invece di chiamare direttamente un interprete di comandi OS (come proc_open / exec in PHP), potremmo dire che queste funzioni sono "di default" più protette contro il comando di iniezione.
D'altra parte dovresti essere consapevole anche degli attacchi "Argument Injection" (potrebbero essere combattuti come Command Injection stesso, ma leggermente diversi). In questo caso, ProcessBuilder è la soluzione sicura con cui andare.
Il motivo è, exec () accetta una stringa e tokenizza / interpreta gli spazi per trasformarla in una matrice di argomenti ma ProcessBuilder no, quindi gli spazi non vengono interpretati per la tokenizzazione delle stringhe !
Esempio di iniezione di argomenti:
}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);
Possibile carico utile:
[email protected] -be ${run{/usr/bin/wget${substr{10}{1}{$tod_log}}http://127.0.0.1/test}}
Dato che è un po 'fuori contesto per questa domanda, lascio qui una ricerca che ho eseguito su quegli attacchi. Questi argomenti potrebbero essere utili a chiunque sia preoccupato della tecnica di utilizzare le funzioni predefinite di Languages per chiamare eseguibile nei file system.
Java CommandI / ArgumentI: link
PHP:
link
Rubino / Python / JS:
link
Fornisco più PoC in cui puoi giocare con i diversi comandi e vedere quali si adattano alle tue specifiche più sicure per l'esecuzione del file di destinazione.