Ich habe an mehreren Stellen den Rat gesehen, die folgende Shebang-Zeile zu verwenden
#!/usr/bin/env bash
anstatt
#!/usr/bin/bash
Meine spontane Reaktion ist: „Was passiert, wenn jemand diese ausführbare Datei beispielsweise durch seine eigene ersetzt ~/.local/bin
?“ Dieses Verzeichnis wird häufig im Pfad des Benutzers vor den systemweiten Pfaden eingerichtet. Ich sehe, dass dies als Sicherheitsproblem häufig eher als Randbemerkung denn als etwas Ernstzunehmendes angesprochen wird, aber ich wollte die Theorie testen.
Um dies auszuprobieren, habe ich so etwas gemacht:
echo -e "#!/usr/bin/python\nprint 'Hacked!'" > $HOME/.local/bin/bash
chmod 755 $HOME/.local/bin/bash
PATH=$HOME/.local/bin env bash
Dies ergibt
/usr/bin/env: ‘bash’: No such file or directory
Um zu prüfen, ob es überhaupt etwas aufnimmt, habe ich auch
echo -e "#!/usr/bin/python\nprint 'Hacked!'" > $HOME/.local/bin/perl
chmod 755 $HOME/.local/bin/perl
PATH=$HOME/.local/bin env perl
das druckt, wie ich erwartet habe,
Hacked!
Kann mir jemand erklären, warum der Ersatz bash
nicht gefunden wird, der Ersatz aber perl
schon? Handelt es sich hier um eine Art „Sicherheitsmaßnahme“, die (aus meiner Sicht) am eigentlichen Zweck vorbeigeht?
EDIT: Weil ich dazu aufgefordert wurde: Ich frage nicht, worin /usr/bin/env bash
der Unterschied zur Verwendung von besteht /bin/bash
. Ich stelle die Frage wie oben angegeben.
EDIT2: Ich muss etwas falsch gemacht haben. Habe es heute noch einmal versucht (mit einem expliziten statt env
einem impliziten Pfad) und es kam zu keinem „nicht gefunden“-Verhalten.
Antwort1
„Was passiert, wenn jemand diese ausführbare Datei beispielsweise in ~/.local/bin durch seine eigene ersetzt?
Dann funktioniert das Skript für sie nicht.
Aber das spielt keine Rolle, da sie das Skript möglicherweise auf andere Weise selbst beschädigen oder ein anderes Programm direkt ausführen könnten, ohne mit PATH
oder in Konflikt zu geraten env
.
Sofern Ihre Benutzer nichtandereBenutzerverzeichnisse in ihren PATH
oder können die Verzeichnisse PATH
anderer Benutzer bearbeiten. Es besteht wirklich keine Möglichkeit, dass ein Benutzer die Verzeichnisse eines anderen Benutzers durcheinanderbringt.
Wenn es sich jedoch nicht um ein Shell-Skript, sondern um etwas handelt, das zusätzliche Berechtigungen gewährt, wie z. B. einen Setuid-Wrapper für ein Programm, dann wäre die Sache anders. In diesem Fall wäre esnotwendigeinen absoluten Pfad zum Ausführen des Programms zu verwenden, es in einem Verzeichnis zu platzieren, das nicht privilegierte Benutzer nicht ändern können, und die Umgebung beim Starten des Programms zu bereinigen.
Antwort2
Was den Unterschied im Verhalten zwischen der Shell und betrifft perl
, perl
prüft die Shell im Gegensatz dazu die erste Zeile, um zu bestimmen, was ausgeführt werden soll:
$ 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
$
Zu den Einsatzmöglichkeiten dieser Funktion gehörenSchreiben von Tests in einer anderen Sprache als PerlMan kann also TAP-kompatible Skripte in anderen Sprachen haben und ein prove
oder ähnliches führt sie korrekt aus.
Antwort3
Hier besteht kein Sicherheitsrisiko. /usr/bin/env
soll die geeignete Binärdatei entsprechend der Benutzerumgebung auswählen. Wenn der Benutzer also seine eigene bash
in installiert hat ~/.local/bin
, /usr/bin/env
sollte er tatsächlich versuchen, diese zu verwenden (er hat möglicherweise beispielsweise eine Version mit zusätzlichen Funktionen kompiliert, die in der systemweiten Version nicht verfügbar sind, und möchte diese anstelle der systemweiten Version verwenden). Dasselbe gilt für jede andere Binärdatei/jeden anderen Interpreter. Es besteht kein Sicherheitsrisiko, da der Benutzer nichts ausführen kann, was er nicht sowieso hätte ausführen können.
Was den Grund angeht, warum der Ersatz in Ihrem Fall fehlschlägt, bezweifle ich, dass es etwas mit zu tun hat /usr/bin/env
. Versuchen Sie PATH=~/.local/bin bash
, , PATH=~/.local/bin bash <path-to-script>
(wie es aufgerufen würde, wenn Sie das Skript ausführen) und auszuführen PATH=~/.local/bin /usr/bin/env bash
und sehen Sie, welche davon fehlschlagen. Das sollte einen Hinweis darauf geben, worauf sich der Fehler „Datei nicht gefunden“ bezieht.