Command- und Argument-Injection verhindern
Quoten, validieren und übergeben Sie nicht vertrauenswürdige Eingaben als Arrays, um Word-Splitting und Injection über eval zu verhindern.
Command- und Argument-Injection verhindern ist eine kostenlose Linux Command Line & Bash Scripting Mastery-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Linux Command Line & Bash Scripting Mastery-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Linux Command Line & Bash Scripting Mastery-Kurs umfasst insgesamt 4 Lektionen.
Warum Injection-Angriffe in Bash auftreten
Bash ist eine leistungsfähige Glue-Sprache — sie übergibt Text direkt an den Kernel, andere Programme und Subshells. Diese Leistungsfähigkeit wird zu einem Sicherheitsrisiko, sobald nicht vertrauenswürdige Eingaben ohne Validierung oder Quoting einen Befehl erreichen.
Fast jeder Bash-Injection liegen zwei Hauptursachen zugrunde:
- Word Splitting: Nicht quotierte Variablen werden an Leerraumzeichen (
IFS) aufgeteilt, sodass aus einem logischen Wert mehrere Shell-Tokens werden. - Glob-Erweiterung: Zeichen wie
*,?und[werden von der Shell erweitert, noch bevor der Befehl ausgeführt wird.
Ein Angreifer, der einen Dateinamen, Benutzernamen, URL-Parameter oder eine Umgebungsvariable kontrolliert, kann beides ausnutzen, um beliebige Befehle auszuführen, Dateien zu lesen oder seine Privilegien auszuweiten.
Diese Lektion zeigt genau, wie solche Schwachstellen entstehen — und vor allem, wie Sie sie durch korrektes Quoting, Eingabevalidierung und die Übergabe von Argumenten über Arrays beseitigen.
Word Splitting: Die unsichtbare Bedrohung
Wenn Bash eine nicht quotierte Variable sieht, teilt sie deren Wert an jedem Zeichen auf, das in $IFS aufgeführt ist (Standard: Leerzeichen, Tabulator, Zeilenumbruch). Was wie ein einziges Argument aussieht, wird zu mehreren.
Führen Sie das folgende Skript aus und beobachten Sie, wie ein Dateiname mit einem Leerzeichen zu zwei separaten Argumenten für rm wird.
#!/usr/bin/env bash
# Dangerous: unquoted variable
FILE='important file.txt'
# Create the file so the demo is self-contained
touch "$FILE"
echo "Files before:"
ls
# BUG: rm sees TWO arguments: 'important' and 'file.txt'
# If 'important' does not exist, rm prints an error but continues.
rm $FILE # <-- unquoted, word-split happens here
echo "Files after (unquoted rm):"
lsImmer quoten: Die erste Regel für defensives Bash
Die einfachste und wirksamste Abwehr gegen Word Splitting besteht darin, Variablenerweiterungen immer in doppelte Anführungszeichen zu setzen.
"$var"— wird genau zu einem Token erweitert und bewahrt Leerzeichen, Tabulatoren und Zeilenumbrüche.'literal'— einfache Anführungszeichen: keinerlei Erweiterungen, geeignet für feste Zeichenketten.- Verwenden Sie
$varniemals ohne Anführungszeichen, außer Sie benötigen ausdrücklich Word Splitting und Glob-Erweiterung.
Das folgende Skript zeigt die sichere Variante des vorherigen Beispiels.
#!/usr/bin/env bash
set -euo pipefail
FILE='important file.txt'
touch "$FILE"
echo 'Files before:'
ls
# SAFE: double-quotes keep the filename as one token
rm "$FILE"
echo 'Files after (quoted rm):'
lsGlob-Injection: Wenn * zur Waffe wird
Nicht quotierte Variablen unterliegen außerdem der Pfadnamenerweiterung (Globbing). Enthält eine benutzerkontrollierte Eingabe * oder ?, erweitert Bash sie anhand des Dateisystems, bevor der Befehl ausgeführt wird.
Ein klassischer Angriffsvektor: Ein Webformular setzt PATTERN=*, und das Skript führt cp $PATTERN /tmp/leak/ aus — dadurch wird jede Datei im aktuellen Verzeichnis kopiert.
Die Lösung ist identisch: Setzen Sie die Variable in doppelte Anführungszeichen. Ein quotiertes "$PATTERN" wird wörtlich übergeben; die Shell führt darauf keine Glob-Erweiterung aus.
#!/usr/bin/env bash
set -euo pipefail
# Simulate attacker-supplied input
PATTERN='*'
mkdir -p /tmp/safe_demo_src /tmp/safe_demo_dst
touch /tmp/safe_demo_src/secret1.txt /tmp/safe_demo_src/secret2.txt
cd /tmp/safe_demo_src
# UNSAFE: glob expands, copies every file
# cp $PATTERN /tmp/safe_demo_dst/
# SAFE: pattern is treated as a literal filename
cp "$PATTERN" /tmp/safe_demo_dst/ 2>&1 || echo 'No file named literally "*" — attack neutralised'
rm -rf /tmp/safe_demo_src /tmp/safe_demo_dstArgument-Injection durch nicht quotierte Positionsparameter
Skripte, die Argumente vom Aufrufer akzeptieren, sind besonders attraktive Ziele für Injection-Angriffe. Jeder Positionsparameter ($1, $2, ...) muss bei jeder Verwendung quotiert werden.
Besonders gefährlich ist es, $@ oder $* ohne Anführungszeichen an einen anderen Befehl zu übergeben:
"$@"— erweitert jeden Positionsparameter zu einem separaten, einzeln quotierten Wort. Verwenden Sie immer diese Form.$@oder$*ohne Anführungszeichen — unterliegen Word Splitting und Globbing."$*"— fügt alle Parameter zu einem Wort zusammen (selten das gewünschte Verhalten).
#!/usr/bin/env bash
set -euo pipefail
# Safe wrapper: forward all arguments quoted
grep_wrapper() {
local pattern="$1"
shift
# "$@" preserves each file argument as one token
grep -rn "$pattern" "$@"
}
# Usage: ./script 'error msg' /var/log/syslog '/path with spaces/app.log'
echo 'Searching current script for "safe":'
grep_wrapper 'safe' "$0"Command-Injection durch eval und nicht validierte Eingaben
eval interpretiert sein Argument erneut als Shell-Code. Alle nicht vertrauenswürdigen Daten, die eval erreichen, können beliebige Befehle ausführen.
Häufige gefährliche Muster:
eval "$user_input"eval echo \$$var(indirekter Variablenzugriff)- Benutzerdaten über
bash -c "$input"übergeben
Regel: Übergeben Sie niemals nicht vertrauenswürdige Eingaben an eval oder bash -c. Verwenden Sie sichere Bash-Alternativen:
- Indirekte Erweiterung:
${!varname}statteval echo \$$varname - Assoziative Arrays für die dynamische Suche nach Schlüssel-Wert-Paaren
- Funktionen statt generierter Befehlszeichenketten
#!/usr/bin/env bash
set -euo pipefail
# Simulated attacker-supplied variable name
VARNAME='PATH; echo INJECTED'
# UNSAFE: eval lets attacker run 'echo INJECTED'
# eval "echo \$$VARNAME"
# SAFE: indirect expansion only resolves valid variable names
# First validate that VARNAME is a legal identifier
if [[ "$VARNAME" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]]; then
echo "Value: ${!VARNAME}"
else
echo "ERROR: invalid variable name: '$VARNAME'" >&2
exit 1
fiEingabevalidierung: Allowlists statt Denylists
Das Zurückweisen bekanntermaßen schädlicher Zeichen (eine Denylist) ist anfällig — Angreifer finden Codierungen oder Zeichen, die Sie übersehen haben. Verwenden Sie stattdessen eine Allowlist: Akzeptieren Sie nur Zeichen, von denen Sie wissen, dass sie sicher sind.
Strategien für Allowlists in Bash:
- Regex-Abgleich:
[[ "$input" =~ ^[A-Za-z0-9_-]+$ ]] - Pattern-Abgleich:
case "$input" in [A-Za-z0-9]*) ... ;; esac - Enum-Prüfung: Vergleich mit einer festen Menge gültiger Werte
Validieren Sie an der Grenze — sobald die Eingabe in das Skript gelangt — und bevor sie irgendeinen Befehl erreicht.
#!/usr/bin/env bash
set -euo pipefail
validate_username() {
local name="$1"
# Allowlist: only lowercase letters, digits, underscore, hyphen; 1-32 chars
if [[ ! "$name" =~ ^[a-z0-9_-]{1,32}$ ]]; then
echo "ERROR: invalid username '${name}'" >&2
return 1
fi
echo "Username accepted: $name"
}
validate_username 'alice' # OK
validate_username 'bob_smith-2' # OK
validate_username 'root; rm -rf /' # REJECTED
validate_username '../etc/passwd' # REJECTEDArgumente sicher mit Arrays übergeben
Wenn Sie einen Befehl dynamisch aufbauen müssen — etwa Flags bedingt hinzufügen oder Eingaben durchlaufen — verwenden Sie ein Bash-Array statt Zeichenketten zu verketten.
Durch die Verkettung von Zeichenketten geht die gesamte Struktur verloren; ein Bash-Array bewahrt jedes Argument als separates Element, ohne erneute Interpretation durch die Shell.
- Deklarieren:
args=() - Anhängen:
args+=(--flag "$value") - Ausführen:
command "${args[@]}"
"${args[@]}" erweitert jedes Element zu einem separaten, einzeln quotierten Wort — genau wie "$@".
#!/usr/bin/env bash
set -euo pipefail
# Build a find command safely with an array
BASEDIR='/tmp'
USER_PATTERN='*.log' # could come from user input (validate first!)
MAX_DAYS=7
cmd=(find "$BASEDIR" -type f -name "$USER_PATTERN" -mtime "+${MAX_DAYS}")
# Optionally add -delete only when requested
DELETE=false
if [[ "$DELETE" == 'true' ]]; then
cmd+=(-delete)
fi
echo "Running: ${cmd[*]}"
"${cmd[@]}"Der ---Separator: Schutz vor Flag-Injection
Selbst ein korrekt quotiertes Argument kann als Option interpretiert werden, wenn es mit - beginnt. Betrachten Sie rm "$file" mit file='-rf .': Das Quoting schützt vor Word Splitting, aber rm interpretiert -rf weiterhin als Flags.
Die POSIX-Konvention -- signalisiert den meisten GNU-/BSD-Werkzeugen das Ende der Optionen. Alles nach -- wird als Positionsargument behandelt, niemals als Flag.
#!/usr/bin/env bash
set -euo pipefail
# Simulate a dangerous filename supplied by the user
FILENAME='-rf /tmp/safe_demo_target'
mkdir -p /tmp/safe_demo_target
touch /tmp/safe_demo_target/keep_me.txt
echo 'Files before:'
ls /tmp/safe_demo_target/
# UNSAFE (flag injection — do NOT uncomment in real systems):
# rm "$FILENAME"
# SAFE: -- ends option processing; filename is treated literally
rm -- "$FILENAME" 2>&1 || echo "No such file (attack neutralised): $FILENAME"
echo 'Files after:'
ls /tmp/safe_demo_target/
rm -rf /tmp/safe_demo_targetEingaben für SQL und externe Werkzeuge bereinigen
Wenn Bash-Skripte Datenbank-CLIs (psql, mysql), curl mit benutzergelieferten URLs oder ähnliche Werkzeuge aufrufen, gelten zwei zusätzliche Ebenen:
- Parametrisierte Abfragen: Interpolieren Sie Benutzerdaten niemals in SQL-Zeichenketten. Übergeben Sie Werte über
-vinpsqloder--data-urlencodeincurl. - Daten und Code trennen: Verwenden Sie
printfmit einer literalen Formatzeichenkette; lassen Sie Benutzereingaben niemals die Formatzeichenkette sein.
Das folgende Beispiel fragt PostgreSQL sicher ab und hält den vom Benutzer gelieferten Wert vollständig aus dem SQL-Text heraus.
#!/usr/bin/env bash
set -euo pipefail
# Validate first: only allow alphanumeric usernames
USERNAME="${1:-alice}"
if [[ ! "$USERNAME" =~ ^[a-z0-9_]{1,32}$ ]]; then
echo 'ERROR: invalid username' >&2
exit 1
fi
# UNSAFE:
# psql -c "SELECT * FROM users WHERE name = '$USERNAME';"
# SAFE: pass value as a psql variable, never inside the SQL text
# psql -v username="$USERNAME" -c 'SELECT * FROM users WHERE name = :username;'
# Demonstrate the principle with printf (safe format string usage)
printf 'Query would use username: %s\n' "$USERNAME"Checkliste zur Absicherung: Alles zusammenführen
Ein produktionsreifes, sicheres Bash-Skript kombiniert alle Techniken dieser Lektion zu einer konsistenten, mehrschichtigen Abwehr. Hier ist eine minimale, aber vollständige Vorlage für ein gehärtetes Skript:
set -euo pipefail— bei Fehlern beenden, nicht gesetzte Variablen als Fehler behandeln und Fehler in Pipelines weitergeben.- Am Einstieg validieren — jede externe Eingabe per Allowlist prüfen, bevor sie einen Befehl erreicht.
- Alles quoten —
"$var","$@","${array[@]}"— ohne Ausnahmen, außer Sie benötigen Splitting. - Arrays verwenden für den dynamischen Aufbau von Befehlen.
- Argumenten
--voranstellen, wenn Sie vom Benutzer gelieferte Dateinamen oder Zeichenketten übergeben. - Niemals
evalverwenden mit nicht vertrauenswürdigen Daten; bevorzugen Sie${!var}für indirekte Zugriffe. - Berechtigungen beschränken — Skripte mit den geringstmöglichen erforderlichen Privilegien ausführen; vermeiden Sie
sudoin Skripten, die Benutzereingaben akzeptieren.
#!/usr/bin/env bash
# Hardened template — safe argument injection prevention
set -euo pipefail
IFS=$'\n\t'
#--- 1. Validate inputs at the boundary ---
SEARCH_DIR="${1:-}"
PATTERN="${2:-}"
[[ -z "$SEARCH_DIR" || -z "$PATTERN" ]] && { echo 'Usage: script <dir> <pattern>' >&2; exit 1; }
[[ ! "$SEARCH_DIR" =~ ^[A-Za-z0-9/_.-]+$ ]] && { echo 'ERROR: unsafe directory path' >&2; exit 1; }
[[ ! "$PATTERN" =~ ^[A-Za-z0-9._-]+$ ]] && { echo 'ERROR: unsafe pattern' >&2; exit 1; }
#--- 2. Build command with an array ---
cmd=(find -- "$SEARCH_DIR" -type f -name "$PATTERN")
#--- 3. Execute — no string interpolation, no eval ---
echo "Executing: ${cmd[*]}"
"${cmd[@]}"Wissenscheck: Quoting und Verhinderung von Injection-Angriffen
Testen Sie Ihr Verständnis der wichtigsten Konzepte dieser Lektion.
Lektionszusammenfassung: Verhindern von Command- und Argument-Injection
Sie haben das vollständige defensive Werkzeugset für die sichere Verarbeitung von Eingaben in Bash behandelt:
- Word Splitting und Glob-Erweiterung sind die grundlegenden Mechanismen, durch die unsichere Variablen zu Injection-Vektoren werden.
- Quoten Sie jede Variable doppelt (
"$var","$@","${arr[@]}"), um beide Bedrohungen zu unterdrücken. - Verwenden Sie beim Weiterreichen von Argumenten
"$@"— niemals$@oder$*ohne Anführungszeichen. - Stellen Sie vom Benutzer gelieferte Dateinamen
--voran, um Flag-Injection zu verhindern. - Erstellen Sie für alle externen Eingaben eine Allowlist mit einer Regex-Prüfung (
[[ $v =~ ^pattern$ ]]), bevor sie einen Befehl erreichen. - Bauen Sie dynamische Befehle mit Arrays auf (
cmd+=()→"${cmd[@]}"), niemals durch Zeichenkettenverkettung. - Entfernen Sie
evalundbash -c "$input"; verwenden Sie${!varname}für eine sichere indirekte Erweiterung. - Beginnen Sie Skripte immer mit
set -euo pipefailundIFS=$'\n\t', um eine solide Basis für die Absicherung zu schaffen.
Diese Praktiken verringern — konsequent ab der ersten Zeile jedes Skripts angewendet — die Angriffsfläche von Bash für Injection-Schwachstellen nahezu auf null.
Häufig gestellte Fragen
Ist die Lektion „Command- und Argument-Injection verhindern“ kostenlos?
Ja — der vollständige Text von „Command- und Argument-Injection verhindern“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Linux Command Line & Bash Scripting Mastery-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Linux Command Line & Bash Scripting Mastery-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Command- und Argument-Injection verhindern“?
Quoten, validieren und übergeben Sie nicht vertrauenswürdige Eingaben als Arrays, um Word-Splitting und Injection über eval zu verhindern. Du übst Linux Command Line & Bash Scripting Mastery mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Linux Command Line & Bash Scripting Mastery zu starten?
Keine Vorkenntnisse erforderlich. Linux Command Line & Bash Scripting Mastery auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.
Wie lange dauert die Lektion „Command- und Argument-Injection verhindern“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Linux Command Line & Bash Scripting Mastery-Lektion Code schreiben und ausführen?
Ja. Jede Linux Command Line & Bash Scripting Mastery-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Command- und Argument-Injection verhindern
- Sichere Geheimnisverwaltung und saubere Umgebungen
- Ausführung mit geringsten Berechtigungen und sudo-Disziplin
- Statische Analyse und Prüfung mit ShellCheck