GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Auswirkungen auf die Sicherheit, wenn vergessen wird, eine Variable in Bash/Posix-Shells zu zitieren?

Wenn Sie unix.stackexchange.com schon eine Weile folgen,
sollten Sie jetzt hoffentlich wissen, dass das Verlassen einer Variablen
ohne Anführungszeichen im Listenkontext (wie in echo $var ) in Bourne/POSIX
-Shells (zsh ist die Ausnahme) hat eine ganz besondere Bedeutung und
sollte nicht gemacht werden, es sei denn, Sie haben einen sehr guten Grund dazu.

Es wird hier ausführlich in einer Reihe von Fragen und Antworten diskutiert (Beispiele:Warum verschluckt sich mein Shell-Skript an Leerzeichen oder anderen Sonderzeichen?, Wann sind doppelte Anführungszeichen erforderlich?, Erweiterung einer Shell-Variablen und Auswirkung von Glob und Split darauf, Zitiert vs. nicht in Anführungszeichen gesetzte Zeichenfolgenerweiterung )

Das ist seit der ersten Veröffentlichung der Bourne
-Shell Ende der 70er Jahre so und wurde auch durch die Korn-Shell
nicht geändert (eines der größten
Bedauern von David Korn (Frage #7 )) oder bash die meistens
die Korn-Shell kopiert haben, und so wurde das von POSIX/Unix spezifiziert.

Jetzt sehen wir hier immer noch eine Reihe von Antworten und sogar
gelegentlich öffentlich veröffentlichten Shell-Code, in dem
Variablen nicht in Anführungszeichen gesetzt werden. Sie hätten gedacht, die Leute hätten
inzwischen gelernt.

Meiner Erfahrung nach gibt es hauptsächlich 3 Arten von Menschen, die es unterlassen,
ihre Variablen zu zitieren:

  • Anfänger. Diese können entschuldigt werden, da es zugegebenermaßen eine
    völlig unintuitive Syntax ist. Und es ist unsere Aufgabe auf dieser Website
    , sie aufzuklären.

  • vergessliche Menschen.

  • Leute, die selbst nach wiederholtem Hämmern nicht überzeugt sind,
    die denken, dass der Bourne-Shell-Autor nicht
    beabsichtigte, dass wir alle unsere Variablen zitieren
    .

Vielleicht können wir sie überzeugen, wenn wir das mit
dieser Art von Verhalten verbundene Risiko aufdecken.

Was ist das Schlimmste, was passieren kann, wenn Sie
vergessen, Ihre Variablen zu zitieren? Ist es wirklich das schlecht?

Von welcher Art von Schwachstelle sprechen wir hier?

In welchen Kontexten kann es ein Problem sein?

Akzeptierte Antwort:

Präambel

Erstens würde ich sagen, dass dies nicht der richtige Weg ist, um das Problem anzugehen.
Es ist ein bisschen so, als würde man sagen:„Du solltest keine Menschen ermorden,
sonst kommst du ins Gefängnis
“.

Ebenso zitieren Sie Ihre Variable nicht, weil Sie sonst
Sicherheitslücken einführen. Sie zitieren Ihre
Variablen, weil es falsch ist, es nicht zu tun (aber wenn die Angst vor dem Gefängnis helfen kann, warum nicht).

Eine kleine Zusammenfassung für diejenigen, die gerade auf den Zug aufgesprungen sind.

In den meisten Shells wird eine Variablenerweiterung ohne Anführungszeichen gelassen (obwohl
das (und der Rest dieser Antwort) auch für die
Befehlsersetzung gilt (`...`). oder $(...) ) und arithmetische Erweiterung ($((...)) oder $[...] )) hat eine ganz besondere
Bedeutung. Der beste Weg, es zu beschreiben ist, dass es wie
das Aufrufen einer Art implizitem split+glob ist Betreiber¹.

cmd $var

in einer anderen Sprache würde so etwas geschrieben werden:

cmd(glob(split($var)))

$var wird zunächst nach komplexen
Regeln unter Einbeziehung des $IFS in eine Liste von Wörtern aufgeteilt speziellen Parameter (der split Teil)
und dann wird jedes Wort, das aus dieser Teilung resultiert, als
ein Muster betrachtet die zu einer Liste von Dateien erweitert wird, die damit übereinstimmen
(die glob Teil).

Als Beispiel, wenn $var enthält *.txt,/var/*.xml und $IFS enthält , , cmd mit einer Reihe von Argumenten aufgerufen werden,
das erste ist cmd und die nächsten sind txt Dateien im aktuellen Verzeichnis und die xml Dateien in /var .

Wenn Sie cmd aufrufen wollten mit nur den beiden wörtlichen Argumenten cmd und *.txt,/var/*.xml , würden Sie schreiben:

cmd "$var"

was in Ihrer anderen vertrauteren Sprache wäre:

cmd($var)

Was meinen wir mit Sicherheitslücke in einer Shell ?

Schließlich ist seit Anbeginn der Zeit bekannt, dass Shell-Skripte
nicht in sicherheitssensiblen Kontexten verwendet werden sollten.
Sicherlich, OK, eine Variable ohne Anführungszeichen zu lassen, ist ein Fehler, aber das kann nicht
so viel Schaden anrichten, oder?

Nun, trotz der Tatsache, dass Ihnen irgendjemand sagen würde, dass Shellskripte
niemals für Web-CGIs verwendet werden sollten, oder dass glücklicherweise
die meisten Systeme heutzutage keine setuid/setgid-Shellskripte erlauben,
eins was Shellshock (der aus der Ferne ausnutzbare Bash-Bug
der im September 2014 für Schlagzeilen sorgte) enthüllte, ist, dass
Shells immer noch ausgiebig dort verwendet werden, wo sie es wahrscheinlich nicht sollten:
in CGIs, in DHCP-Clients Hook-Skripte, in Sudoers-Befehlen,
aufgerufen von (wenn nicht als ) setuid-Befehle…

Manchmal unbewusst. Zum Beispiel system('cmd $PATH_INFO') in einem php /perl /python Das CGI-Skript ruft eine Shell auf, um diese Befehlszeile zu interpretieren (ganz zu schweigen von der Tatsache, dass cmd selbst kann ein Shell-Skript sein und sein
Autor hätte nie erwartet, dass es von einem CGI aufgerufen wird).

Sie haben eine Schwachstelle, wenn es einen Weg zur Rechteerweiterung gibt,
wenn jemand (nennen wir ihn den Angreifer )
kann etwas tun, was er nicht tun soll.

Damit ist immer der Angreifer gemeint Bereitstellung von Daten, wobei diese Daten
von einem privilegierten Benutzer/Prozess verarbeitet werden, der versehentlich
etwas tut, was er nicht tun sollte, in den meisten Fällen aufgrund
eines Fehlers.

Grundsätzlich haben Sie ein Problem, wenn Ihr fehlerhafter Code
Daten unter der Kontrolle des Angreifers verarbeitet .

Nun, es ist nicht immer offensichtlich, wo sich diese Daten befinden stammen kann,
und es ist oft schwer zu sagen, ob Ihr Code jemals
nicht vertrauenswürdige Daten verarbeiten kann.

Soweit Variablen betroffen sind, im Fall eines CGI-Skripts
ist es ganz offensichtlich, dass die Daten die CGI GET/POST-Parameter und
Dinge wie Cookies, Pfad, Host … Parameter sind.

Bei einem setuid-Skript (das als ein Benutzer ausgeführt wird, wenn es von
einem anderen aufgerufen wird) sind es die Argumente oder Umgebungsvariablen.

Ein weiterer sehr häufiger Vektor sind Dateinamen. Wenn Sie eine
Dateiliste aus einem Verzeichnis erhalten, ist es möglich, dass der Angreifer dort Dateien
eingeschleust hat .

In dieser Hinsicht könnten Sie sogar an der Eingabeaufforderung einer interaktiven Shell
anfällig sein (bei der Verarbeitung von Dateien in /tmp oder ~/tmp zum Beispiel).

Sogar ein ~/.bashrc kann angreifbar sein (zum Beispiel bash wird es
interpretieren, wenn es über ssh aufgerufen wird um einen ForcedCommand auszuführen wie in git Serverbereitstellungen mit einigen Variablen unter der
Kontrolle des Clients).

Nun darf ein Skript nicht direkt aufgerufen werden, um nicht vertrauenswürdige
Daten zu verarbeiten, aber es kann von einem anderen Befehl aufgerufen werden, der dies tut. Oder Ihr
falscher Code kann in Skripte kopiert und eingefügt werden, die dies tun (von Ihnen
Jahre später oder einem Ihrer Kollegen). Ein Ort, an dem es
besonders kritisch ist ist in Antworten auf Q&A-Sites enthalten, da Sie
nie wissen, wo Kopien Ihres Codes landen können.

Zur Sache; wie schlimm ist es?

Eine Variable (oder Befehlsersetzung) ohne Anführungszeichen zu lassen, ist bei weitem
die häufigste Quelle für Sicherheitslücken im Zusammenhang
mit Shell-Code. Zum Teil, weil sich diese Fehler oft in
Schwachstellen niederschlagen, aber auch, weil es so häufig vorkommt, dass Variablen ohne Anführungszeichen
zu sehen sind.

Verwandte:Warum sollte ich install statt cp und mkdir verwenden?

Wenn Sie nach Schwachstellen im Shell-Code suchen, ist das erste, was Sie tun müssen,
nach nicht in Anführungszeichen gesetzten Variablen zu suchen. Es ist leicht
zu erkennen, oft ein guter Kandidat, im Allgemeinen leicht auf
vom Angreifer kontrollierte Daten zurückzuverfolgen.

Es gibt unendlich viele Möglichkeiten, wie eine nicht in Anführungszeichen gesetzte Variable
zu einer Schwachstelle werden kann. Ich nenne hier nur ein paar allgemeine Trends.

Offenlegung von Informationen

Die meisten Leute werden wegen der Aufteilung auf Fehler stoßen, die mit nicht in Anführungszeichen gesetzten
Variablen verbunden sind part (zum Beispiel ist es
heutzutage üblich, dass Dateien Leerzeichen in ihren Namen haben und Leerzeichen
ist im Standardwert von IFS). Viele Leute werden den Glob übersehen Teil. Der Glob Teil ist mindestens so gefährlich wie der Split Teil.

Globbing bei nicht bereinigter externer Eingabe bedeutet den
Angreifer
kann Sie dazu bringen, den Inhalt eines beliebigen Verzeichnisses zu lesen.

In:

echo You entered: $unsanitised_external_input

wenn $unsanitised_external_input enthält /* , das heißt der
Angreifer
kann den Inhalt von / sehen . Keine große Sache. Interessanter wird es aber
mit /home/* was Ihnen eine Liste von
Benutzernamen auf dem Rechner gibt, /tmp/* , /home/*/.forward für
Hinweise auf andere gefährliche Praktiken, /etc/rc*/* für aktivierte
Dienste… Sie müssen sie nicht einzeln benennen. Ein Wert von /* /*/* /*/*/*... listet nur das gesamte Dateisystem auf.

Denial-of-Service-Schwachstellen.

Wenn wir den vorherigen Fall etwas zu weit treiben, haben wir eine DoS.

Tatsächlich ist jede nicht in Anführungszeichen gesetzte Variable im Listenkontext mit nicht bereinigter
Eingabe mindestens eine DoS-Schwachstelle.

Sogar erfahrene Shell-Skripter vergessen häufig Dinge zu zitieren
wie:

#! /bin/sh -
: ${QUERYSTRING=$1}

: ist der no-op-Befehl. Was könnte schief gehen?

Das soll $1 zuweisen zu $QUERYSTRING wenn $QUERYSTRING war ungesetzt. Das ist eine schnelle Möglichkeit, ein CGI-Skript auch von
der Befehlszeile aus aufrufbar zu machen.

Dieser $QUERYSTRING ist aber immer noch expandiert und weil es
nicht in Anführungszeichen steht, wird split+glob Operator aufgerufen wird.

Nun, es gibt einige Globs, deren Erweiterung
besonders teuer ist. Der /*/*/*/* man ist schon schlimm genug, da es bedeutet,
Verzeichnisse bis zu 4 Ebenen tiefer aufzulisten. Zusätzlich zur Festplatten- und CPU
-Aktivität bedeutet dies das Speichern von Zehntausenden von Dateipfaden
(40 KB hier auf einer minimalen Server-VM, davon 10 K Verzeichnisse).

Jetzt /*/*/*/*/../../../../*/*/*/* bedeutet 40k x 10k und /*/*/*/*/../../../../*/*/*/*/../../../../*/*/*/* ist genug, um
selbst die mächtigste Maschine in die Knie zu zwingen.

Probieren Sie es selbst aus (aber machen Sie sich darauf gefasst, dass Ihr Rechner
abstürzt oder sich aufhängt):

a='/*/*/*/*/../../../../*/*/*/*/../../../../*/*/*/*' sh -c ': ${a=foo}'

Natürlich, wenn der Code ist:

echo $QUERYSTRING > /some/file

Dann können Sie die Diskette füllen.

Führen Sie einfach eine Google-Suche nach Shell
cgi oder bash
cgi oder ksh
cgi durch, und Sie werden
ein paar Seiten finden, die Ihnen zeigen, wie man CGIs in Shells schreibt. Beachten Sie
, wie die Hälfte derjenigen, die Parameter verarbeiten, anfällig ist.

Sogar David Korns
eigener
ist angreifbar (siehe Cookie-Handhabung).

bis hin zu Schwachstellen bei der Ausführung willkürlichen Codes

Die Ausführung willkürlichen Codes ist die schlimmste Art von Schwachstelle,
seit dem Angreifer kann jeden Befehl ausführen, es gibt keine Beschränkung
was er tun darf.

Das ist im Allgemeinen die Aufteilung Teil, der zu denen führt. Diese
Aufteilung führt dazu, dass mehrere Argumente an Befehle übergeben werden,
wenn nur eines erwartet wird. Während der erste davon
im erwarteten Kontext verwendet wird, stehen die anderen in einem anderen Kontext
und werden daher möglicherweise anders interpretiert. Besser mit einem Beispiel:

awk -v foo=$external_input '$2 == foo'

Hier sollte der Inhalt des $external_input zugewiesen werden Shell-Variable zum foo awk Variable.

Jetzt:

$ external_input='x BEGIN{system("uname")}'
$ awk -v foo=$external_input '$2 == foo'
Linux

Das zweite Wort, das aus der Aufspaltung von $external_input resultiert ist foo nicht zugewiesen aber als awk betrachtet code (hier, der
einen beliebigen Befehl ausführt:uname ).

Das ist besonders ein Problem bei Befehlen, die andere
Befehle ausführen können (awk , env , sed (GNU one), perl , find …) besonders
mit den GNU-Varianten (die Optionen nach Argumenten akzeptieren).
Manchmal würde man nicht vermuten, dass Befehle
andere wie ksh ausführen können , bash oder zsh ist [ oder printf

for file in *; do
  [ -f $file ] || continue
  something-that-would-be-dangerous-if-$file-were-a-directory
done

Wenn wir ein Verzeichnis namens x -o yes erstellen , dann wird der Test
positiv, da es sich um einen völlig anderen
bedingten Ausdruck handelt, den wir auswerten.

Schlimmer noch, wenn wir eine Datei namens x -a a[0$(uname>&2)] -gt 1 erstellen ,
mindestens mit allen ksh-Implementierungen (einschließlich sh der meisten kommerziellen Unices und einiger BSDs), das uname ausführt weil diese Shells eine arithmetische Auswertung der
numerischen Vergleichsoperatoren von [ durchführen Befehl.

$ touch x 'x -a a[0$(uname>&2)] -gt 1'
$ ksh -c 'for f in *; do [ -f $f ]; done'
Linux

Dasselbe gilt für bash für einen Dateinamen wie x -a -v a[0$(uname>&2)] .

Wenn sie keine willkürliche Hinrichtung erreichen können, natürlich der Angreifer kann
sich mit geringerem Schaden begnügen (was zu einer willkürlichen
Hinrichtung beitragen kann). Jeder Befehl, der Dateien schreiben oder
Berechtigungen oder Eigentumsrechte ändern oder Haupt- oder Nebeneffekte haben kann, könnte ausgenutzt werden.

Mit Dateinamen kann man allerhand machen.

$ touch -- '-R ..'
$ for file in *; do [ -f "$file" ] && chmod +w $file; done

Und am Ende machen Sie .. beschreibbar (rekursiv mit GNU chmod ).

Skripte zur automatischen Verarbeitung von Dateien in öffentlich beschreibbaren Bereichen wie /tmp sind sehr sorgfältig zu schreiben.

Was ist mit [ $# -gt 1 ]

Das ist etwas, was ich ärgerlich finde. Einige Leute machen sich
die Mühe, sich zu fragen, ob eine bestimmte Erweiterung
problematisch sein könnte, um zu entscheiden, ob sie die Anführungszeichen weglassen können.

Es ist wie gesagt. Hey, es sieht aus wie $# kann nicht dem split+glob-Operator
unterworfen werden, lassen Sie uns die Shell bitten, ihn zu splitten+glob
.
Oder Hey, schreiben wir falschen Code, nur weil der Fehler
unwahrscheinlich ist
.

Wie unwahrscheinlich ist es nun? OK, $# (oder $! , $? oder jede
arithmetische Substitution) dürfen nur Ziffern (oder -) enthalten für
einige²) also der glob Teil ist raus. Für die Aufteilung Teil, um
etwas zu tun, alles, was wir brauchen, ist $IFS Ziffern enthalten (oder - ).

Bei einigen Shells $IFS kann von der Umgebung geerbt werden,
aber wenn die Umgebung nicht sicher ist, ist das Spiel sowieso vorbei.

Verwandt:Die Umleitung zu einem globbed-Dateinamen schlägt fehl?

Wenn Sie nun eine Funktion schreiben wie:

my_function() {
  [ $# -eq 2 ] || return
  ...
}

Das bedeutet, dass das Verhalten Ihrer Funktion
vom Kontext abhängt, in dem sie aufgerufen wird. Oder mit anderen Worten $IFS wird einer der Eingänge dazu. Wenn Sie
die API-Dokumentation für Ihre Funktion schreiben, sollte sie genau genommen
so aussehen:

# my_function
#   inputs:
#     $1: source directory
#     $2: destination directory
#   $IFS: used to split $#, expected not to contain digits...

Und Code, der Ihre Funktion aufruft, muss sicherstellen, dass $IFS enthält keine
Ziffern. All das, weil Sie keine Lust hatten,
diese zwei doppelten Anführungszeichen einzugeben.

Nun, dafür [ $# -eq 2 ] Bug zu einer Sicherheitslücke zu machen,
müssten Sie irgendwie für den Wert von $IFS benötigen unter
Kontrolle des Angreifers geraten . Es ist denkbar, dass das normalerweise
nicht passieren würde, es sei denn der Angreifer konnte einen weiteren Fehler ausnutzen.

Das ist jedoch nicht unerhört. Ein häufiger Fall ist, dass Leute
vergessen, Daten zu bereinigen, bevor sie in arithmetischen
Ausdrücken verwendet werden. Wir haben oben bereits gesehen, dass es in einigen Shells
die Ausführung willkürlichen Codes erlauben kann, aber in allen erlaubt es dem Angreifer um jeder Variablen einen ganzzahligen Wert zu geben.

Zum Beispiel:

n=$(($1 + 1))
if [ $# -gt 2 ]; then
  echo >&2 "Too many arguments"
  exit 1
fi

Und mit einem $1 mit dem Wert (IFS=-1234567890) , diese arithmetische
Auswertung hat den Nebeneffekt der Einstellungen IFS und des nächsten [ Befehl schlägt fehl, was bedeutet, dass die Prüfung auf zu viele Argumente erfolgt wird
umgangen.

Was ist, wenn split+glob Operator wird nicht aufgerufen?

Es gibt einen anderen Fall, in dem Anführungszeichen um Variablen und andere Erweiterungen benötigt werden:wenn es als Muster verwendet wird.

[[ $a = $b ]]   # a `ksh` construct also supported by `bash`
case $a in ($b) ...; esac

teste nicht, ob $a und $b sind gleich (außer bei zsh ), aber wenn $a stimmt mit dem Muster in $b überein . Und Sie müssen $b in Anführungszeichen setzen wenn Sie als Zeichenfolgen vergleichen möchten (das Gleiche in "${a#$b}" oder "${a%$b}" oder "${a##*$b*}" wobei $b sollte zitiert werden, wenn es nicht als Muster zu verstehen ist).

Das bedeutet, dass [[ $a = $b ]] kann wahr zurückgeben, wenn $a unterscheidet sich von $b (zum Beispiel wenn $a ist anything und $b ist * ) oder kann false zurückgeben, wenn sie identisch sind (zum Beispiel wenn beide $a und $b sind [a] ).

Kann das eine Sicherheitslücke darstellen? Ja, wie jeder Fehler. Hier, der Angreifer kann den logischen Codefluss Ihres Skripts ändern und/oder die Annahmen, die Ihr Skript macht, zunichte machen. Zum Beispiel mit einem Code wie:

if [[ $1 = $2 ]]; then
   echo >&2 '$1 and $2 cannot be the same or damage will incur'
   exit 1
fi

Der Angreifer kann die Prüfung umgehen, indem '[a]' '[a]' übergeben wird .

Wenn nun weder dieses Muster noch split+glob übereinstimmen Operator anwenden, was ist die Gefahr, eine Variable ohne Anführungszeichen zu lassen?

Ich muss zugeben, dass ich schreibe:

a=$b
case $a in...

Dort schadet das Zitieren nicht, ist aber nicht zwingend erforderlich.

Ein Nebeneffekt des Weglassens von Anführungszeichen in diesen Fällen (z. B. in Q&A-Antworten) besteht jedoch darin, dass es Anfängern eine falsche Nachricht senden kann:dass es in Ordnung sein kann, Variablen nicht in Anführungszeichen zu setzen .

Zum Beispiel könnten sie anfangen zu denken, dass wenn a=$b OK ist, dann export a=$b wäre es auch (was in vielen Shells nicht der Fall ist, da es in Argumenten für den export steht Befehl so im Listenkontext) oder env a=$b .

Was ist mit zsh ?

zsh hat die meisten dieser Design-Schwierigkeiten behoben. In zsh (zumindest wenn nicht im sh/ksh-Emulationsmodus), wenn Sie aufteilen möchten , oder globbing , oder Musterabgleich , muss explizit angefordert werden:$=var zu teilen, und $~var zu glob oder damit der Inhalt der Variablen als Muster behandelt wird.

Das Aufteilen (aber nicht das Globbing) erfolgt jedoch immer noch implizit bei der Ersetzung von Befehlen ohne Anführungszeichen (wie in echo $(cmd)). ).

Außerdem ist ein manchmal unerwünschter Nebeneffekt des Nichtzitierens von Variablen das Entfernen von Leerzeichen . Die zsh Das Verhalten ähnelt dem, was Sie in anderen Shells erreichen können, indem Sie Globbing vollständig deaktivieren (mit set -f ) und Splitten (mit IFS='' ). Immer noch in:

cmd $var

Es wird kein split+glob geben , aber wenn $var leer ist, anstatt ein leeres Argument zu erhalten, cmd erhält überhaupt kein Argument.

Das kann Fehler verursachen (wie das offensichtliche [ -n $var ] ). Dies kann möglicherweise die Erwartungen und Annahmen eines Skripts zunichte machen und Schwachstellen verursachen.

Da die leere Variable dazu führen kann, dass ein Argument einfach entfernt wird , das heißt, das nächste Argument könnte im falschen Kontext interpretiert werden.

Als Beispiel,

printf '[%d] <%s>n' 1 $attacker_supplied1 2 $attacker_supplied2

Wenn $attacker_supplied1 leer ist, dann $attacker_supplied2 wird als arithmetischer Ausdruck interpretiert (für %d ) anstelle eines Strings (für %s ) und alle nicht bereinigten Daten, die in einem arithmetischen Ausdruck verwendet werden, stellen eine Command Injection-Schwachstelle in Korn-ähnlichen Shells wie zsh dar.

$ attacker_supplied1='x y' attacker_supplied2='*'
$ printf '[%d] <%s>n' 1 $attacker_supplied1 2 $attacker_supplied2
[1] <x y>
[2] <*>

gut, aber:

$ attacker_supplied1='' attacker_supplied2='psvar[$(uname>&2)0]'
$ printf '[%d] <%s>n' 1 $attacker_supplied1 2 $attacker_supplied2
Linux
[1] <2>
[0] <>

Der uname willkürlicher Befehl ausgeführt wurde.

Was ist, wenn Sie tun brauchen den split+glob Betreiber?

Ja, das ist normalerweise der Fall, wenn Sie Ihre Variable ohne Anführungszeichen lassen möchten. Aber dann müssen Sie sicherstellen, dass Sie Ihren Split einstellen und Glob Bediener richtig, bevor Sie es verwenden. Wenn Sie nur die Aufteilung wollen Teil und nicht die Glob Teil (was meistens der Fall ist), dann müssen Sie Globbing deaktivieren (set -o noglob /set -f ) und $IFS reparieren . Andernfalls verursachen Sie auch Sicherheitslücken (wie das oben erwähnte CGI-Beispiel von David Korn).

Schlussfolgerung

Kurz gesagt, eine Variable (oder Befehlssubstitution oder
arithmetische Erweiterung) in Shells ohne Anführungszeichen zu lassen, kann sehr gefährlich sein
, besonders wenn es im falschen Kontext gemacht wird, und es ist sehr
schwer zu wissen, welche das sind diese falschen Kontexte.

Das ist einer der Gründe, warum es als schlechte Praxis angesehen wird .

Danke fürs Lesen. Wenn es Ihnen über den Kopf wächst, machen Sie sich
keine Sorgen. Man kann nicht erwarten, dass jeder alle Implikationen des
Schreibens seines Codes so versteht, wie er ihn schreibt. Deshalb haben wir Empfehlungen für bewährte Verfahren , sodass sie befolgt werden können, ohne
notwendigerweise zu verstehen, warum.

Verwandte:Wie berechnet man den Durchschnitt der Werte in einer Spalte, indem man die Informationen aus einer anderen Spalte berücksichtigt?

(und falls das noch nicht offensichtlich ist, vermeiden Sie es bitte,
sicherheitsrelevanten Code in Shells zu schreiben).

Und bitte zitieren Sie Ihre Variablen in Ihren Antworten auf dieser Seite!


Linux
  1. Anpassen der Bash-Shell

  2. Bash-Scripting(I)

  3. Bash Dynamische (Variable) Variablennamen?

  4. Funktionen in Shell-Variablen?

  5. Welche Bash wird ausgeführt?

.bashrc vs. .bash_profile

So setzen Sie die Umgebungsvariable in Bash

Bash Beginner Series #2:Variables in Bash Shell Scripting verstehen

Was ist Subshell in Linux?

Unterschied zwischen einfachen und doppelten Anführungszeichen in Bash Shell

8 Arten von Linux-Shells