flawopen.com/Command Injection/Java Runtime.exec()
Runtime.exec() em Java é seguro contra Command Injection?
Runtime.exec(String) não executa um shell implicitamente, portanto operadores de shell não são interpretados automaticamente. Ainda assim, a string é dividida em programa e argumentos, e texto não confiável pode alterar os argumentos recebidos pelo programa. ProcessBuilder deixa as fronteiras explícitas; valide cada valor e limite o executável e as opções permitidas.
// Entrada do usuário é concatenada à string do comando Runtime.getRuntime().exec( "approved-tool --input " + filename );
// Executável fixo e argumentos separados; valide filename primeiro String safeName = validateFilename(filename); new ProcessBuilder( "/opt/app/bin/approved-tool", "--input", safeName ).start();
Injeção em shell e injeção de argumentos são diferentes
Desde o Java 18, a Oracle marca Runtime.exec(String) como obsoleto por ser propenso a erros e recomenda exec(String[]) ou ProcessBuilder. A sobrecarga de string separa tokens por espaços em branco, podendo dividir argumentos como caminhos que contêm espaços. Runtime.exec(String) não inicia implicitamente sh nem outro shell; a documentação da Oracle descreve a conversão da string em um array de argumentos. Isso impede que metacaracteres comuns sejam tratados como sintaxe de shell, mas não torna a entrada confiável: a tokenização ainda pode criar argumentos adicionais, e o programa pode interpretar um argumento como opção. ProcessBuilder recebe uma lista de strings com o executável e os argumentos; em plataformas comuns, cada elemento define uma fronteira. Mantenha o executável fixo, valide os valores conforme a gramática esperada pelo programa e rejeite ou trate valores que pareçam opções. Use -- apenas quando a documentação do programa garantir esse comportamento. Não invoque um shell explicitamente, como sh -c, com entrada não confiável.
Perguntas frequentes
Não. Isso reduz o risco de injeção em shell nesse overload, mas ainda é possível injetar argumentos. O programa pode interpretar entradas controladas pelo atacante como opções ou nomes de arquivo. Use ProcessBuilder com executável fixo e argumentos separados e valide cada valor conforme o programa.
Não. Ele monta a lista de programa e argumentos e inicia um processo; não verifica se são seguros ou válidos. Aplique allowlists e validação na aplicação e siga as regras de argumentos documentadas pelo programa.