Se eu entendi corretamente, var
é uma variável na sua linguagem de programação.
E na sua linguagem de programação, você está pedindo a um shell para interpretar uma string que é a concatenação de "cd "
, o conteúdo dessa variável e "; echo > create_a_file_here"
.
Se então, sim, se o conteúdo de var
não for rigidamente controlado, é uma vulnerabilidade de injeção de comando.
Você pode tentar citar corretamente o conteúdo da variável¹ na sintaxe do shell, portanto, é garantido que ele seja passado como um único argumento para o cd
builtin.
Outra abordagem seria passar o conteúdo dessa variável de outra maneira. Uma maneira óbvia seria passar isso em uma variável de ambiente. Por exemplo, em C:
char *var = "; rm -rf /";
setenv("DIR", var, 1);
system("CDPATH= cd -P -- \"$DIR\" && echo something > create_a_file_here");
Desta vez, o código que você pede ao shell para interpretar é fixo, ainda precisamos escrevê-lo corretamente na sintaxe do shell (aqui assumido como sendo um shell compatível com POSIX):
-
A expansão de variável de shell
- deve ser citada para evitar o split + glob
- você precisa de
-P
paracd
para fazer um simpleschdir()
- você precisa de
--
para marcar o final das opções para evitar problemas comvar
começando com-
(ou+
em alguns shells) - Definimos
CDPATH
para a sequência vazia, caso ela esteja no ambiente - Só executamos o comando
echo
secd
foi bem-sucedido.
Há (pelo menos) um problema remanescente: se var
for -
, ele não entrará no diretório chamado -
, mas no diretório anterior (conforme armazenado em $OLDPWD
) e OLDPWD=- CDPATH= cd -P -- "$DIR"
não é garantido para contornar isso. Então você precisaria de algo como:
system(
"case $DIR in\n"
" (-) CDPATH= cd -P ./-;;\n"
" (*) CDPATH= cd -P -- \"$DIR\";;\n"
"esac && ....");
¹ Note que apenas fazendo um é não o caminho a seguir, você estaria apenas movendo o problema. system(concat("cd \"", var, "\"; echo..."));
Por exemplo, um var = "$(rm -rf /)"
ainda seria um problema.
A forma confiável somente de citar texto para shells parecidos com Bourne é usar aspas simples e também cuidar das aspas simples que podem ocorrer na string. Por exemplo, ative um char *var = "ab'cd"
para char *escaped_var = "'ab'\''cd'"
. Ou seja, substitua todos os '
para '\''
e coloque a coisa toda dentro de '...'
.
Isso ainda pressupõe que essa string citada não seja usada em backticks e você ainda precisa do --
, -P
, &&
, CDPATH=
...