
He visto consejos en varios lugares para usar la siguiente línea shebang
#!/usr/bin/env bash
en lugar de
#!/usr/bin/bash
Mi reacción instintiva es: "¿Qué pasa si alguien sustituye este ejecutable por el suyo propio ~/.local/bin
?" Ese directorio a menudo se configura en la ruta del usuario antes que las rutas de todo el sistema. Considero que esto se plantea como una cuestión de seguridad, a menudo como una nota al margen y no como algo que deba tomarse en serio, pero quería probar la teoría.
Para probar esto hice algo como esto:
echo -e "#!/usr/bin/python\nprint 'Hacked!'" > $HOME/.local/bin/bash
chmod 755 $HOME/.local/bin/bash
PATH=$HOME/.local/bin env bash
Esto produce
/usr/bin/env: ‘bash’: No such file or directory
Para comprobar si estaba captando algo, también lo hice.
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 esperaba,
Hacked!
¿Alguien puede explicarme por qué bash
no se encuentra el sustituto, pero perl
sí el sustituto? ¿Se trata de algún tipo de medida de "seguridad" que (desde mi punto de vista) no tiene sentido?
EDITAR: Porque me preguntaron: no estoy preguntando en qué /usr/bin/env bash
se diferencia de usar /bin/bash
. Estoy haciendo la pregunta como se indicó anteriormente.
EDIT2: Debe haber sido algo que estaba haciendo mal. Lo intenté nuevamente hoy (usando una ruta explícita en env
lugar de implícita) y no se produjo ese comportamiento de "no encontrado".
Respuesta1
"¿Qué pasa si alguien sustituye este ejecutable por el suyo propio en, por ejemplo, ~/.local/bin ?
Entonces el guión no les funciona.
Pero eso no importa, ya que posiblemente podrían romper el script por sí mismos de otras maneras, o ejecutar otro programa directamente sin alterar PATH
o env
.
A menos que sus usuarios tenganotroLos directorios de los usuarios en su PATH
, o pueden editar los PATH
de otros usuarios, realmente no hay posibilidad de que un usuario se meta con otro.
Sin embargo, si no fuera un script de shell, sino algo que otorga privilegios adicionales, como un contenedor setuid para algún programa, entonces las cosas serían diferentes. En ese caso, seríanecesariopara utilizar una ruta absoluta para ejecutar el programa, colóquelo en un directorio que los usuarios sin privilegios no puedan modificar y limpie el entorno al iniciar el programa.
Respuesta2
En cuanto a la diferencia de comportamiento entre Shell y perl
, perl
a diferencia de Shell, inspecciona la primera línea para determinar qué ejecutar:
$ 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
$
Los usos de esta característica incluyenescribir pruebas en algún otro idioma además de perlpor lo que uno puede tener scripts compatibles con TAP en otros idiomas y prove
algo así los ejecutará correctamente.
Respuesta3
No hay ningún riesgo de seguridad aquí. /usr/bin/env
Se supone que debe seleccionar el binario apropiado según el entorno del usuario. Entonces, si el usuario ha instalado el suyo propio bash
en ~/.local/bin
, entonces /usr/bin/env
debería intentar usarlo (puede, por ejemplo, haber compilado una versión con características adicionales que no están disponibles en la versión para todo el sistema y preferiría usarlo en lugar de la versión para todo el sistema). Lo mismo ocurre con cualquier otro binario/intérprete. No hay ningún riesgo de seguridad, porque el usuario no podrá ejecutar nada que no hubiera podido ejecutar de todos modos.
En cuanto a por qué el sustituto está fallando en su caso, dudo que tenga algo que ver /usr/bin/env
. Intente ejecutar PATH=~/.local/bin bash
( PATH=~/.local/bin bash <path-to-script>
como se llamaría cuando ejecute el script) y PATH=~/.local/bin /usr/bin/env bash
vea cuál de ellos falla. Eso debería dar una pista de a qué se refiere el error "archivo no encontrado".