ADMIN

2021

03

2021-03-01T12:00:00

IT-Automatisierung

SCHWERPUNKT

064

Automatisierung

Ansible

Sichere Shell-Skripte schreiben

Kleinvieh macht auch Mist

von Tam Hanna

Veröffentlicht in Ausgabe 03/2021 - SCHWERPUNKT

Holistische Systemsicherheit bedeutet, auch dem kleinsten Teil Aufmerksamkeit zu widmen, auf dass es nicht als Einfallsloch in das System dient. Ein Beispiel für kleine, wenig beachtete, aber dennoch potenziell sehr gefährliche Teile der IT sind Shell-Skripte. Sie sorgen immer wieder für ernste Sicherheitsprobleme, weshalb wir Best Practices zur sicheren Skript-Programmierung präsentieren.

Einen eindrucksvollen Beleg für die mögliche Schädlichkeit von Shell-Skripten lieferte das amerikanische Softwareunternehmen Valve. Die Linux-basierte Version des Spielediensts Steam brachte ein Skript mit, das normalerweise nur für kleinere Einrichtungsaufgaben zuständig war. Verhängnisvollerweise [1] fand sich dort folgende Passage:
rm -rf "$STEAMROOT/"*
Dieses für das Löschen des Verzeichnisses "$STEAMROOT" verantwortliche Kommando bekommt Probleme, wenn die Umgebungsvariable nicht gesetzt ist. Die Bash-Shell löst dann keinen Fehler aus, sondern "zerlegt" die Umgebungsvariable einfach zu einem leeren String. Lohn der Mühen ist folgendes Kommando, das sich rekursiv durch das gesamte Dateisystem arbeitet und alle Informationen zerstört:
rm -rf "/"*.
Einige Benutzer entgingen einem Totalverlust dadurch, dass ihre Steam-Ausführungsumgebung unter SELinux-Jail lief. Andere waren nicht so glücklich, weshalb es an der Zeit ist, sich Maßnahmen zur defensiven Programmierung von Shell-Skripten näher anzusehen.
Einen eindrucksvollen Beleg für die mögliche Schädlichkeit von Shell-Skripten lieferte das amerikanische Softwareunternehmen Valve. Die Linux-basierte Version des Spielediensts Steam brachte ein Skript mit, das normalerweise nur für kleinere Einrichtungsaufgaben zuständig war. Verhängnisvollerweise [1] fand sich dort folgende Passage:
rm -rf "$STEAMROOT/"*
Dieses für das Löschen des Verzeichnisses "$STEAMROOT" verantwortliche Kommando bekommt Probleme, wenn die Umgebungsvariable nicht gesetzt ist. Die Bash-Shell löst dann keinen Fehler aus, sondern "zerlegt" die Umgebungsvariable einfach zu einem leeren String. Lohn der Mühen ist folgendes Kommando, das sich rekursiv durch das gesamte Dateisystem arbeitet und alle Informationen zerstört:
rm -rf "/"*.
Einige Benutzer entgingen einem Totalverlust dadurch, dass ihre Steam-Ausführungsumgebung unter SELinux-Jail lief. Andere waren nicht so glücklich, weshalb es an der Zeit ist, sich Maßnahmen zur defensiven Programmierung von Shell-Skripten näher anzusehen.
Shell-Variante festlegen
Unter unixoiden Betriebssystemen stehen Dutzende von Shells zur Verfügung, die sich nur durch die Unterstützung des POSIX-Standards ähneln und diverse proprietäre Funktionen mitbringen. Bei der Nutzung von Shell-spezifischem Code in anderen Shells tritt oft ein undefiniertes Verhalten auf. Dies mag in einer kontrollierten VM-Umgebung kein Problem sein, doch das Deployment in einem Docker- oder sonstigem Cluster ändert die Lage.
Das häufigste Problem ist die Verwendung der als Shebang bezeichneten Sequenz "#!/bin/sh", die gemäß POSIX-Standard die vom System vorausgewählte Shell betrifft. Ein Shebang ist unter Unix eine mit "#!" beginnende erste Zeile eines Skripts. Sie legt fest, welcher Interpreter für die Abarbeitung des Skripts zu verwenden ist. In der Literatur finden sich dafür auch die Begriffe sha-bang, hash-bang, pound-bang oder hash-pling.
Die unter Skriptprogrammierern weit verbreitete Bash ist nur selten die Standard-Shell. Auf unserer auf Ubuntu 18.04 basierten Workstation lässt sich dies durch Eingabe des which-Kommandos prüfen. So liefert which sh die Ausgabe "/bin/sh" zurück und der Befehl which bash ergibt "/bin/bash". Zur Umgehung des Problems stehen mehrere Methoden zur Verfügung. Am einfachsten ist es, im Shebang explizit die Verwendung der Bash-Shell über #!/bin/bash anzuweisen. Insbesondere in Cloudumgebungen gilt, dass es nicht vernünftig ist, das Vorhandensein der Bash-Shell anzunehmen. Wer sein Skript ohne spezifische Instruktionen aufbaut, spart sich beim Deployment Aufwand.
Bild 1: Mit dem checkbashisms-Befehl lässt sich Bash-spezifischer Code identifizieren.
Der checkbashisms-Befehl hilft Administratoren dabei, Bash-spezifische Programmelemente zu finden und zu beseitigen. Zur Installation des Werkzeugs müssen Sie das Paket "devscripts" laden. Danach erzeugen wir ein kleines Shell-Skript, das eine Bash-spezifische For-Schleife enthält:
!#/bin/sh
for ((i=0; i<3; i++)); do echo "$i"
done
Wenn Sie dieses Skript mit check­bashisms analysieren, beschwert es sich über die Schleife (Bild 1). Wichtig ist, dass das Werkzeug Bash-spezifischen Code nur moniert, wenn der Shebang nicht auf die Bash verweist. Die folgende Version passiert die checkbashisms-Kontrolle ohne Probleme:
#!/bin/bash
for ((i=0; i<3; i++)); do echo "$i"
done
Passwörter sicher speichern
Administratoren verwenden Shell-Skripte gerne zur Automatisierung von Systemaufgaben, etwa zum Kopieren von Dateien oder dem Aktualisieren von auf Servern befindlichen Informationen. Dazu sind ein Passwort und/oder ein Benutzername erforderlich, die Sie nicht mit der Allgemeinheit teilen sollten.
Andererseits müssen Sie die Credentials zur Verfügung stellen, da Sie diese sonst bei jeder Ausführung des Skripts von Hand eingeben müssen. Angreifer erbeuten auf gekaperten Systemen gern alle Shell-Skripte, die sie bekommen. Finden sie dabei eine Gruppe von Passwörtern, potenziert sich der entstandene Schaden.
Der erste Weg zum Erfüllen dieser Bedingung besteht darin, die Credentials über Parameter an das Skript zu übergeben. Hierzu wäre folgende Vorgehensweise geeignet, wobei die Variablen "$1" und "$2" für den ersten und zweiten Parameter stehen:
#!/bin/bash
a=$1
b=$2
while [ TRUE ]; do sleep 1;
done
Die Ausführung erfolgt per ./itaworker.sh tam pass. Dies ist aus sicherheitstechnischer Sicht kritisch. Das Linux-Kommandozeilenwerkzeug "ps" zur Auflistung laufender Prozesse gibt auf Wunsch die zum Aufruf übergebenen Parameter aus. Bild 2 zeigt, wie ein Angreifer in diesem Fall die Credentials frei Haus geliefert bekommt – die Eingabe von ps ist eine der ersten Aktionen eines Angreifers.
Bild 2: Die Verwendung von Parametern mit Credentials ist der Sicherheit nicht zuträglich.
Sofern die dynamische Parametrisierung des Shell-Skripts unbedingt erforderlich ist, empfiehlt sich die Auslagerung der Credentials in Umgebungsvariablen. Diese lassen sich durch einen gewöhnlichen ps-Scan nicht finden, denn der Zugriff auf "/proc/self/environ" setzt bei korrekter Konfiguration fortgeschrittene Benutzerrechte voraus. Diese Vorgehensweise ist allerdings auch nicht universell akzeptiert – das Linux Documentation Project [2] empfiehlt, die Informationen über eine Pipe oder eine Redirection zu liefern.
In der Literatur herrscht durch die Bank Einigkeit, dass es auf jeden Fall besser ist, wenn sich das Passwort nicht im Klartext in der Skriptdatei findet. Ein Weg zum Erreichen dieses Ziels ist die Verwendung einer umkehrbaren Hash-Funktion, die ihre als Salt bezeichneten Ausgabewerte wieder in den Ursprungswert konvertiert.
Sofern Sie für die Salt-Rückumwandlung ein Programm verwenden, dass der Angreifer bei einem Scan nicht erwischt, erschweren sie ihm das Leben. Denn möchte er die Credentials im Klartext haben, muss er sich nochmals einloggen und das Kommando zur Ausführung bringen. Im Idealfall gehört die Binärdatei dann einem Benutzer, der ausschließlich für die Shell-Skript-Ausführung verantwortlich ist.
Möglichkeit Nummer zwei setzt (Bild 3) auf eine separate Konfigurationsdatei, die andere Leserechte aufweist. Sofern der für die Ausführung der Skripte verantwortliche User der Einzige ist, der diese Datei lesen darf, ist ein Angriff auf die anderen Benutzerkonten in Bezug auf Credentials unkritisch.
Bild 3: Das Unix-Benutzerrechtesystem schützt die Passwortkonfigurationsdatei vor unberechtigten Zugriffen.
Um die Struktur des Skripts zu verstecken, bietet sich die von Francisco Rosales entwickelte Software SHC [3] an. Das Paket lässt sich unter Ubuntu über den Paketmanager installieren. Der Aufruf erwartet den Parameter "-f" zum Festlegen der Quelldatei:
shc -f itaworker.sh
 
ls itaworker.sh
Nach der Abarbeitung finden wir zwei zusätzliche Dateien: Neben der ausführbaren Datei mit der Endung ".X" finden wir auch ein File namens ".X.C", das den C-Code des Skripts bereitstellt.
SHC verpackt das Shell-Skript in einen C-Wrapper, den es danach über den C-Compiler in eine Binärdatei umwandelt. Löschen Sie die Dateien "itaworker.sh" und "itaworker.sh.x.c", ist es für den Angreifer danach schwieriger, den Code des Skripts zu erbeuten. Angemerkt sei, dass die große Verbreitung von SHC dazu geführt hat, dass es Dekompilationswerkzeuge gibt [4].
Temporäre Dateien als Sicherheitslücke
Ein Skript muss die Credentials anderen Applikationen zur Verfügung stellen. Hierzu kommen gern temporäre Dateien zum Einsatz. Legen Sie das File im Ordner "/tmp/" an, sollte es nach der Skript-Abarbeitung verschwinden. Ein klassisches Beispiel dafür ist folgendes Skript, das eine Datei mit einem Passwort anlegt:
#!/bin/sh
SECRETDATA="Der ITA sendet Gruesse"
echo > /tmp/mydata
chmod og-rwx /tmp/mydata
echo "$SECRETDATA" > /tmp/mydata
Probleme treten auf, wenn ein Angreifer die Temporärdatei über die sehr schnell reagierende Filesystem-Watcher-API überwacht. Im Fall des vorliegenden Skripts könnte er fopen aufrufen und die Datei als geöffnet markieren, um die abgelegten Informationen sofort oder später abzuernten.
Wie zuvor bei den Plaintext-Passwörtern gilt auch hier, dass der sicherste Weg der ist, die Credentials nicht in eine temporäre Datei zu schreiben. Ist dies zur Erfüllung der Funktion jedoch notwendig, bietet sich folgender Weg an:
#!/bin/sh
SECRETDATA="ITA sendet Gruesse"
umask 0177
FILENAME="$(mktemp/tmp/mytempfile.XXXXXX)"
echo "$SECRETDATA" > "$FILENAME"
Der umask-Befehl weist neu erzeugten Dateien die als Parameter übergebenen Zugriffsattribute zu. Zweitens erzeugen Sie durch das mktemp-Kommando einen jedes Mal zufälligen Dateinamen, was das Konfigurieren der Watcher-API erschwert. Zahlreiche Quellen sehen die Verwendung temporärer Dateien in Shell-Skripten allgemein kritisch. Unter [5] finden Sie eine Liste von Schwachstellen, die im Zusammenhang mit Tempfiles auftreten.
Benutzereingaben gegen Fehl-Parsings absichern
Häufigster Kritikpunkt gegen die Shell-Ausführungsumgebung ist die unzureichende Ausstattung mit Methoden zur String-Verarbeitung. Im Zusammenspiel mit der Möglichkeit, Variablen direkt an die Shell zu übergeben, entstehen gravierende Sicherheitslücken. Ein absoluter Klassiker ist das vorliegende Skript, das einen Parameter von STDIN einliest und diesen per eval-Befehl ausführt:
#!/bin/bash
read BAR
eval $BAR
Der eval-Befehl ist normalerweise zum Ausführen von Berechnungen und harmlosen Kommandos vorgesehen. Eine legitime Vorgehensweise wäre das Anliefern des folgenden Echo-Kommandos (bei Bedarf mit einem Pipe-Redirect):
./itaworker.sh
echo hello
Ein bösartiger User übergibt an dieser Stelle keinen Echo-Aufruf samt Redirection, sondern ein Kommando wie das weiter oben erwähnte "rm". Die Shell erkennt dies prinzipbedingt nicht, weshalb das Skript Daten zerstört.
Da manche eval-basierten Aufgabenstellungen ohne dieses Kommando überhaupt nicht machbar sind, monieren Shell-Überprüfungswerkzeuge wie "shellcheck" die Verwendung des Kommandos nicht – das vorliegende Skript würde die Fehlermeldung "Double quote to prevent globbing and word splitting.” auslösen, die sich folgendermaßen beheben lässt:
#!/bin/bash
read BAR
eval "$BAR"
Da diese Änderung aber keine Verifikation der in "BAR" enthaltenen Werte durchführt, ist die Sicherheitslücke nicht behoben. Aus sicherheitstechnischer Sicht ist der einzig richtige Weg zum Handhaben des eval-Kommandos dessen Nicht-Nutzung. Ist dies keine Option, achten Sie darauf, die eingegebenen Kommandos auf Strings wie "rm" und auf nicht alphanumerische Zeichen zu überprüfen.
Abfragen sind ein weiterer Weg, um Probleme zu provozieren. Im nächsten Beispiel wollen wir ein Skript ansehen, das überprüft, ob der Benutzer den String "foo" eingibt. Die Payload, die hier nur aus einem Aufruf von Echo besteht, soll nur bei Eingabe von "foo" zur Ausführung gelangen:
#!/bin/bash
read FOO
if [ x$FOO = xfoo ] ; then echo $FOO
fi
Bei einer oberflächlichen Überprüfung der Skriptverhaltens sehen wir, dass beispielsweise die Eingabe "itahallo" nicht zur Ausführung der Payload führt. Übergeben wir jedoch einen String nach dem Schema "foo = xfoo -<beliebig>", kommt die Payload trotzdem zur Abarbeitung:
./itaworker.sh
foo = xfoo -o sdjs
foo = xfoo -o sdjs
~$
Der Schadensfall tritt auf, wenn statt der Echo-Payload etwas Empfindlicheres wie ein eval-Aufruf abzusichern ist. Im schlimmsten Fall befindet sich in der Payload dann ein Kommando, das aufgrund der ungültigen Werte Schaden anrichtet.
Zur Umgehung des Problems bietet sich – wie auch in anderen Einsatzszenarien der Shell – die Verwendung von Quoting an:
if [ "$FOO" = "foo" ] ; then echo $FOO
fi
Die "neue" Version des Skripts evaluiert den Inhalt der Variable komplett, was die Abweisung von ungültigen Eingaben zur Folge hat:
./itaworker.sh
foo
foo
./itaworker.sh
foo = xfoo
Bei der Arbeit mit älteren Shells ist das Quoting noch wichtiger. Ein nach dem folgenden Schema aufgebautes Programm ließe sich durch Eingabe von einem per Semikolon aufgeteilten String zum Ausführen von beliebigem Code animieren:
#!/bin/sh
read VAL
echo $VAL
Ursache dieses Problems ist, dass ältere Shells keine Parsing-Läufe durchführen, bevor sie die Variable substituieren – das Semikolon würde das Kommando auftrennen und den darauffolgenden Teil zur Ausführung bringen.
Parsingfehler ausschließen
Die recht archaische Sprachsyntax sorgt mitunter für seltsames Verhalten wie im folgenden Beispiel, das die Datei "/bin/werkzeug_VAR" aufrufen soll:
ENV_VAR="fehlwert"
ENV="werkzeug"
echo /bin/$ENV_VAR
Wenn Sie es in der Kommandozeile ausführen, sehen Sie, dass es den in der Variable "ENV_VAR" gespeicherten Wert verwendet. Die Shell trennt "echo /bin/ $ENV_VAR" am Unterstrich ab. Zur Umgehung dieses Problems ist es empfehlenswert, prinzipiell alle Variablenzugriffe in geschwungene Klammern zu setzen. Eine korrigierte Version unseres Skripts sieht folgendermaßen aus:
ENV_VAR="fehlwert"
ENV="werkzeug"
echo /bin/${ENV}_VAR
Das Ausführen des korrigierten Skripts zeigt, dass der ausgegebene String nun richtig ist:
./itaworker.sh
/bin/werkzeug_VAR
Problem Nummer zwei betrifft die Analyse von Benutzerberechtigungen unter Verwendung der Shell. Mit "$UID" und "$USER" stehen zwei Variablen zur Verfügung, die sich zur Analyse der Berechtigungen des gerade aktiven Benutzers einspannen lassen, etwa:
if [ $UID = 100 -a $USER = "myusername" ] ; then
           cd $HOME
fi
Leider ist nicht sichergestellt, dass die beiden Variablen zur Laufzeit wirklich den Wert enthalten, der dem ak­tiven Benutzer entspricht. Während zahlreiche Shells mittlerweile die Variable "$UID" sichern, gilt dies meist nicht für "$USER" – in älteren Shells ist es sogar möglich, beide Variablen mit beliebigen Werten auszustatten. Zur Umgehung dieses Problems bietet es sich an, Benutzername und User-ID durch Aufrufen von Betriebssystemkommandos zu ermitteln. Die so zurückgegebenen Werte lassen sich nur durch Setzen der Path-Variable beeinflussen, was den Angriff verkompliziert.
In besonders kritischen Ausführungsumgebungen ist stets ratsam, die Utility-Pfade immer voll auszuschreiben. Rufen Sie "Echo" beispielsweise über seinen Pfad "/bin/echo" auf, ist das aktivierte Programm von der Path-Variablen unabhängig.
Abschließend sei noch auf den Umstand hin­gewiesen, dass die Bash-Shell eine "Spezialversion" des Shebangs kennt (#!/bin/bash -p). Diese Variante weist die Shell dazu an, die Dateien ".bashrc" und ".profile" nicht im Rahmen des Starts auszuführen. Die Variable "SHELL­OPTS" und die in "ENV" und "BASH_ENV" angelegten Startskripte fallen in diesem Betriebsmodus ebenfalls unter den Tisch. Sinn dieser Vorgehensweise ist, dass vom Angreifer durchgeführte Manipulationen der Umgebung nicht durch zufällige Skript-Ausführungen aktivierbar sind.
Link-Codes
[2] Linux Documentation Project: https://tldp.org/
[5] Sicherer Einsatz von Temp-Dateien: https://www.netmeister.org/blog/mktemp.html/
[8] Shellcheck im Web: https://www.shellcheck.net/
Strengere Verifikation der Ausführung aktivieren
Shell-Skripte sind für Nicht-Programmierer vorgesehen, die damit häufige Aufgaben in ihrem täglichen Leben mit UNIX-Betriebssystemen beschleunigen. Als Entgegenkommen an diese Nutzerschicht sind so gut wie alle Shells "permissiv" eingestellt: Im Fall eines Fehlers versuchen diese, das Skript weiter auszuführen. Diese für einen weniger technisch versierten Nutzer durchaus freundliche Vorgehensweise ist kritisch, weil Sicherheitsprobleme verursachende Zweideutigkeiten die Abarbeitung des Skripts nicht beenden.
Das zuvor genannte Problem der Zerstörung von Dateien wäre bei folgender Einstellung der Shell nicht aufgetreten:
#!/bin/bash
set -o nounset
TAMS_VAR="fehlwert"
echo /bin/${ENV}_VAR
Der set-Befehl aktiviert bei Aufruf mit dem Parameter "-o" Ausführungsoptionen, die das Laufzeitverhalten des Interpreters beeinflussen. Wir verwenden hier "nounset", was nicht gesetzte Variablen als Fehler betrachtet. Die Ausführung des zuvor gezeigten Shell-Skripts scheitert nun mit dem in Bild 4 gezeigten Fehler.
Bild 4: Die Option "nounset" beendet die Programmausführung beim Antreffen nicht existierender Variablen.
Mit set -o errexit erfolgt eine Programmbeendigung, wenn ein vom Shell-Skript ausgerufener Befehl nicht den Rückgabewert null zurückgibt. Sein Einsatz lässt sich durch Kopieren einer nicht vorhandenen Datei überprüfen:
#!/bin/bash
set -o errexit
cp "existiertnicht" "baum.txt"
echo "Kopieren erfolgreich"
Das cp-Kommado liefert keine Null zurück, wenn es einen Parameter nicht findet, weshalb die an Echo übergebene Statusmeldung nicht in der Kommandozeile erscheint.
In Skripten gibt es immer wieder Situationen, in denen ein Teil des zu erledigenden Codes unkritisch ist und die per "-o" festgelegten Befehle sich durch Aufruf von "+o" deaktivieren lassen. Im folgenden Skript ist die errexit-Option bei der Abarbeitung des Kopierbefehls nicht mehr aktiv:
#!/bin/bash
set -o errexit
set +o errexit
cp "existiertnicht" "baum.txt"
echo "Kopieren erfolgreich"
Zu guter Letzt sei noch auf ein Problem bei der Verarbeitung von per Pipe verbundenen Kommandos hingewiesen. Normalerweise scheitert ein derartiger Befehl nur, wenn das in der Pipe-Folge letzte Kommando nicht den Wert null zurückliefert. Sollen Fehler irgendwo in der Hierarchie für einen Abbruch sorgen, aktivieren Sie die Option "pipefail" per set -o pipefail.
Funktionen verändern globale Variable
Ein weiterer Nebeneffekt der laxen Sprachsyntax ist, dass in Unterfunktionen definierte Variablen unerwartete Nebeneffekte entwickeln. Als Beispiel wollen wir uns ein Skript ansehen, das die Variable "o" sowohl innerhalb als auch außerhalb einer Funktion verwendet:
#!/bin/bash
 
hello_world () {
      o=2
      echo 'hello, world'
}
 
o=1
echo $o
hello_world
echo $o
Mit anderen Skriptsprachen aufgewachsene Entwickler erwarten, dass beide Aufrufe von "echo $o" den Wert "1" zurückgeben. Von Haus aus ist dem nicht so, die in der Funktion durchgeführten Änderungen bleiben auch nach ihrer Ausführung gültig . Zur Behebung des Problems reicht es aus, die Variablen in der Funktion mit dem local-Schlüsselwort auszustatten:
#!/bin/bash
 
hello_world () {
      local o=2
      echo 'hello, world'
}
 
o=1
echo $o
hello_world
echo $o
Obwohl längere Shell-Skripte aus Wartungsaspekten nicht unbedingt empfehlenswert sind, sollten Sie in Funktionen verwendete Variablen immer über das Schlüsselwort "local" absichern. Recycelt ein Kollege irgendwann doch Shell-Code, ist er vor unerwarteten Nebeneffekten besser geschützt.
Automatische Shell-Skript-Prüfung mit Shellcheck
C- und C++-Programmierer prüfen die Ergebnisse ihrer Arbeit seit langer Zeit durch statische Analyse. Ein statisches Analysewerkzeug hat eine Wissensbasis, in der es Programmierfehler vorhält und diese gegen den vorliegenden Code anwendet. Für Shell-Skripte steht mit Shellcheck [6] ein ähnliches Werkzeug zur Verfügung. Das unter der GPLv3 stehende Tool verhält sich von der Syntax her analog zu Lint – es erwartet als Parameter den Namen der Shell-Datei, den es auf unsaubere Elemente überprüft.
ShellCheck sucht nicht nur nach sicherheitsrelevanten Fehlern. In der unter [7] bereitstehenden Liste finden sich vier Dutzend Testkriterien, die auch allgemeine Programmierfehler erkennen und monieren. Zu guter Letzt gibt es unter [8] noch eine Webversion des Werkzeugs, die sich mit Skripten füttern lässt und diese ohne lokale Installation auf Korrektheit und Sicherheit überprüft.
Fazit
Die enge Integration zwischen Skripten und der für die Ausführung von Kommandos vorgesehenen Shell sorgt im Zusammenspiel mit einer laxen Syntax-Verifikation dafür, dass eine unsaubere Shell-Programmierung schnell beeindruckend gefährliche Sicherheitslücken produziert.
Die hier vorgestellten Kriterien umschiffen den Gutteil der Probleme. Anders als bei komplizierten Sicherheitslücken ist im Fall von Shell-Skripten die Ursache meist schlichtes Unverständnis dessen, dass eine bestimmte Konstruktion Nebeneffekte entfaltet.
(jp)