/ usr / bin / env como um shebang - e sua implicação de segurança [duplicado]

13

Eu tenho visto conselhos em vários lugares para usar a seguinte linha de shebang

#!/usr/bin/env bash

em vez de

#!/usr/bin/bash

Minha reação automática é: "e se alguém substituir esse executável por si mesmo em ~/.local/bin ?" Esse diretório geralmente é configurado no caminho do usuário antes dos caminhos do sistema. Eu vejo isso como uma questão de segurança, muitas vezes como uma nota lateral, em vez de qualquer coisa para levar a sério, mas eu queria testar a teoria.

Para testar isso, 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 produz

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

Para verificar se estava pegando 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 bash não foi encontrado, mas o substituto perl é? Isso é algum tipo de medida de "segurança" que (do meu ponto de vista) perde o ponto?

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

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

    
por taifwa 10.04.2017 / 13:59

3 respostas

17

"what if somebody substitutes this executable for their own in say ~/.local/bin ?

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

Mas isso não importa, já que eles podem conseguir quebrar o script de outras maneiras ou executar outro programa diretamente sem mexer em PATH ou env .

A menos que seus usuários tenham diretórios outros usuários em PATH , ou possam editar o PATH de outros usuários, não há realmente a possibilidade de um usuário atrapalhar 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, as coisas seriam diferentes. Nesse caso, seria necessário usar um caminho absoluto para executar o programa, colocá-lo em um diretório que os usuários não privilegiados não podem modificar e limpar o ambiente ao iniciar o programa.

    
por 10.04.2017 / 14:44
4

Quanto à diferença de comportamento entre o shell e o perl , perl , diferentemente do shell, inspeciona a primeira linha para determinar o que deve ser executado:

$ 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 incluem testes de escrita em algum outro idioma além do perl assim, pode-se ter scripts compatíveis com TAP em outros idiomas e um prove ou algo assim os executará corretamente.

    
por 10.04.2017 / 16:06
1

Não há risco de segurança aqui. /usr/bin/env deve selecionar o binário apropriado de acordo com o ambiente do usuário. Portanto, se o usuário tiver instalado seu próprio bash em ~/.local/bin , então /usr/bin/env deve tentar usá-lo (eles podem, por exemplo, ter compilado uma versão com recursos extras que não estão disponíveis no sistema) versão, e preferiria usá-lo no lugar da versão de todo o sistema). O mesmo vale para qualquer outro binário / intérprete. 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ê executar o script) e PATH=~/.local/bin /usr/bin/env bash e ver quais falharão. Isso deve dar uma pista sobre o que o erro "arquivo não encontrado" está se referindo.

    
por 11.04.2017 / 09:52