/usr/bin/env como um shebang - e suas implicações de segurança

/usr/bin/env como um shebang - e suas implicações de segurança

Eu vi conselhos em vários lugares para usar a seguinte linha shebang

#!/usr/bin/env bash

em vez de

#!/usr/bin/bash

Minha reação instintiva é: "e se alguém substituir este executável pelo seu próprio em say ~/.local/bin?" Esse diretório geralmente é configurado no caminho do usuário antes dos caminhos de todo o sistema. Vejo isso levantado como uma questão de segurança, muitas vezes como uma observação lateral, e não como algo a ser levado a sério, mas queria testar a teoria.

Para testar isso eu fiz algo assim:

echo -e "#!/usr/bin/python\nprint 'Hacked!'" > $HOME/.local/bin/bash
chmod 755 $HOME/.local/bin/bash
PATH=$HOME/.local/bin env bash

Isso rende

/usr/bin/env: ‘bash’: No such file or directory

Para verificar se estava captando alguma coisa, eu também fiz

echo -e "#!/usr/bin/python\nprint 'Hacked!'" > $HOME/.local/bin/perl
chmod 755 $HOME/.local/bin/perl
PATH=$HOME/.local/bin env perl

que imprime, como eu esperava,

Hacked!

Alguém pode me explicar por que o substituto bashnão foi encontrado, mas o substituto perlsim? Isso é algum tipo de medida de "segurança" que (do meu ponto de vista) não entende o objetivo?

EDIT: Porque fui solicitado: não estou perguntando como /usr/bin/env bashé diferente de usar /bin/bash. Estou fazendo a pergunta conforme indicado acima.

EDIT2: Deve ter sido algo que eu estava fazendo errado. Tentei novamente hoje (usando o caminho explícito em envvez do implícito) e nenhum comportamento "não encontrado".

Responder1

"e se alguém substituir este executável pelo seu próprio, digamos ~/.local/bin ?

Então o script não funciona para eles.

Mas isso não importa, já que eles poderiam quebrar o script de outras maneiras ou executar outro programa diretamente, sem mexer com PATHou env.

A menos que seus usuários tenhamoutrodiretórios de usuários em seus diretórios PATH, ou pode editar os PATHde outros usuários, não há realmente nenhuma possibilidade de um usuário bagunçar outro.


No entanto, se não fosse um script de shell, mas algo que conceda privilégios adicionais, como um wrapper setuid para algum programa, então as coisas seriam diferentes. Nesse caso, serianecessáriopara usar um caminho absoluto para executar o programa, coloque-o em um diretório que usuários sem privilégios não possam modificar e limpe o ambiente ao iniciar o programa.

Responder2

Quanto à diferença de comportamento entre o shell e o perl, perlao contrário do shell inspeciona a primeira linha para determinar o que executar:

$ cat tcl
#!/usr/bin/env tclsh
puts "TCL running as [pid]"
$ perl tcl
TCL running as 39689
$ cat sbcl
#!/opt/local/bin/sbcl --script
(format t "~a running as ~a~%" 'lisp (sb-unix:unix-getpid))
$ perl sbcl
LISP running as 39766
$ 

Os usos desse recurso incluemescrevendo testes em alguma outra linguagem além do perlentão é possível ter scripts compatíveis com TAP em outros idiomas e provealgo assim irá executá-los corretamente.

Responder3

Não há risco de segurança aqui. /usr/bin/envdeve selecionar o binário apropriado de acordo com o ambiente do usuário. Portanto, se o usuário instalou o seu próprio bashno ~/.local/bin, então /usr/bin/envdeveria tentar usá-lo (ele pode, por exemplo, ter compilado uma versão com recursos extras que não estão disponíveis na versão para todo o sistema e preferiria usá-lo no lugar da versão para todo o sistema). O mesmo vale para qualquer outro binário/interpretador. Não há risco de segurança, porque o usuário não poderá executar nada que não seria capaz de executar de qualquer maneira.

Quanto ao motivo pelo qual o substituto está falhando no seu caso, duvido que tenha algo a ver com /usr/bin/env. Tente executar PATH=~/.local/bin bash, PATH=~/.local/bin bash <path-to-script>(como seria chamado quando você executa o script) e PATH=~/.local/bin /usr/bin/env bashveja qual deles falha. Isso deve dar uma pista sobre a que se refere o erro "arquivo não encontrado".

informação relacionada