Não há nenhuma divisão de palavras (como no recurso que divide variáveis em expansões sem aspas) nesse código, pois $myvar
não é sem aspas.
Há, no entanto, uma vulnerabilidade de injeção de comando, pois $myvar
é expandido antes de ser passado para bash
. Então, seu conteúdo é interpretado como código bash!
Os espaços nele farão com que vários argumentos sejam passados para cd
, não por causa da divisão de palavras , mas porque eles serão analisados como vários tokens na sintaxe do shell. Com um valor de bye;reboot
, isso irá reiniciar! ¹
Aqui, você deseja:
sudo bash -c 'cd -P -- "$1"' bash "$myvar"
(onde você passa o conteúdo de $myvar
como o primeiro argumento desse script in-line; observe como $myvar
e $1
foram citados para seus respectivos shell para evitar a divisão de palavras IFS (e globbing)) .
Ou:
sudo MYVAR="$myvar" bash -c 'cd -P -- "$MYVAR"'
(onde você passa o conteúdo de $myvar
em uma variável de ambiente).
É claro que você não conseguirá nada útil executando somente cd
nesse script inline (além de verificar se root
pode cd
para lá). Presumivelmente, você quer aquele script para cd
lá e então faz algo mais como:
sudo bash -c 'cd -P -- "$1" && do-something' bash "$myvar"
Se a intenção era usar sudo
para poder cd
em um diretório ao qual você não tem acesso, então isso não funciona.
sudo sh -c 'cd -P -- "$1" && exec bash' sh "$myvar"
iniciará um bash
interativo com seu diretório atual em $myvar
. Mas esse shell estará sendo executado como root
.
Você poderia fazer:
sudo sh -c 'cd -P -- "$1" && exec sudo -u "$SUDO_USER" bash' sh "$myvar"
Para obter um bash
interativo e sem privilégios, com o diretório atual sendo $myvar
, mas se você não tiver as permissões para cd
nesse diretório, não conseguirá fazer nada nesse diretório, mesmo que seja seu diretório de trabalho atual.
$ myvar=/var/spool/cron/crontabs
$ sudo sh -c 'cd -P -- "$1" && exec sudo -u "$SUDO_USER" bash' sh "$myvar"
bash-4.4$ ls
ls: cannot open directory '.': Permission denied
Uma exceção seria se você tiver a permissão pesquisa para o diretório em si, mas não para um dos componentes de diretório de seu caminho:
$ myvar=1/2
$ mkdir -p "$myvar"
$ chmod 0 1
$ cd 1/2
cd: permission denied: 1/2
$ sudo sh -c 'cd -P -- "$1" && exec sudo -u "$SUDO_USER" bash' sh "$myvar"
bash-4.4$ pwd
/home/stephane/1/2
bash-4.4$ mkdir 3
bash-4.4$ ls
3
bash-4.4$ cd "$PWD"
bash: cd: /home/stephane/1/2: Permission denied
¹ estritamente falando, para valores de $myvar
como $(seq 10)
(literalmente), haveria a divisão de palavras naturalmente após a expansão dessa substituição de comando pelo bash
shell iniciado como root