/ usr / bin / env en tant que shebang – et son implication en matière de security

J'ai vu des conseils dans plusieurs endroits pour utiliser la ligne de shebang suivante

#!/usr/bin/env bash 

au lieu de

 #!/usr/bin/bash 

Ma réaction réflexe est, "et si quelqu'un substitue cet exécutable pour lui-même en disant ~/.local/bin ?" Ce directory est souvent configuré dans le path de l'user avant les paths à l'échelle du système. Je considère cela comme une question de security souvent comme une note de côté plutôt que comme une question à prendre au sérieux, mais je voulais tester la théorie.

Pour essayer ceci, j'ai fait quelque chose comme ça:

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

Cela produit

 /usr/bin/env: 'bash': No such file or directory 

Pour vérifier s'il ramassait quoi que ce soit, j'ai aussi fait

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

qui imprime, comme prévu,

 Hacked! 

Quelqu'un peut-il m'expliquer pourquoi le substitut bash n'est pas trouvé, mais le substitut perl est? Est-ce une sorte de mesure de "security" qui (de mon sharepoint vue) manque le point?

EDIT: Parce que j'ai été invité: Je ne request pas comment /usr/bin/env bash est différent de /bin/bash . Je pose la question comme indiqué ci-dessus.

EDIT2: Ça devait être quelque chose que je faisais mal. Essayé encore aujourd'hui (en utilisant le path explicite à env au lieu d'implicite), et pas un tel comportement "introuvable".

"que se passe-t-il si quelqu'un substitue cet exécutable pour lui-même en disant ~ / .local / bin?

Ensuite, le script ne fonctionne pas pour eux.

Mais cela n'a pas d'importance, car ils pourraient éventuellement se briser le script pour eux-mêmes d'autres façons, ou exécuter un autre programme directement sans jouer avec PATH ou env .

À less que vos users aient des directorys d' autres users dans leur PATH , ou qu'ils puissent modifier le PATH d'autres users, il n'y a vraiment aucune possibilité qu'un user en décode un autre.


Cependant, si ce n'était pas un script shell, mais quelque chose qui accorde des privilèges supplémentaires, comme un wrapper setuid pour un programme, les choses seraient différentes. Dans ce cas, il est nécessaire d'utiliser un path absolu pour exécuter le programme, le placer dans un directory que les users non privilégiés ne peuvent pas modifier et nettoyer l'environnement lors du démarrage du programme.

Quant à la différence de comportement entre le shell et le perl , perl contrairement au shell inspecte la première ligne pour déterminer ce qu'il faut exécuter:

 $ 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 $ 

Les utilisations de cette fonctionnalité incluent l' écriture de tests dans une autre langue en plus de perl, de sorte que l'on peut avoir des scripts compatibles TAP dans d'autres langues et une prove ou quoi ne fonctionnera pas correctement.

Il n'y a pas de risque de security ici. /usr/bin/env est supposé sélectionner le binary approprié en fonction de l'environnement de l'user. Donc, si l'user a installé son propre bash dans ~/.local/bin , alors /usr/bin/env doit en effet essayer de l'utiliser (ils peuvent par exemple comstackr une version avec des fonctionnalités supplémentaires qui ne sont pas disponibles dans la version à l'échelle du système, et préfèrerait l'utiliser à la place de la version à l'échelle du système). La même chose vaut pour tout autre binary / interprète. Il n'y a pas de risque pour la security, car l'user ne pourra pas exécuter quoi que ce soit qu'il n'aurait pas pu exécuter de toute façon.

Quant à savoir pourquoi le substitut échoue dans votre cas, je doute que cela ait quelque chose à voir avec /usr/bin/env . Essayez d'exécuter PATH=~/.local/bin bash , PATH=~/.local/bin bash <path-to-script> (comme on l'appelle quand vous exécutez le script) et PATH=~/.local/bin /usr/bin/env bash et voyez lesquelles échouent. Cela devrait donner un indice quant à ce que l'erreur "file introuvable" fait reference.