Angenommen, ich habe ein Bash-Skript, das als Konfigurationsdatei für ein anderes Bash-Skript fungiert:
config.sh:
verbose=yes
echo "Malicious code!"
name=test
script.sh:
source config.sh
echo "After sourcing: verbose='$verbose', name='$name'"
Das Problem ist, dass dies nicht sehr sicher ist, da alles, was in config.sh abgelegt ist, ausgeführt wird:
$ ./script.sh
Malicious code!
After sourcing: verbose='yes', name='test'
Um es sicherer zu machen, dachte ich, ich würde Zuweisungsoperationen ausgraben und nur diese ausführen. Ich würde dies erreichen, indem ich source
ein "hier-Dokument" übergebe:
script.sh:
source <<EOF
$(grep -P '^\s*\w+=' test.sh)
EOF
echo "After sourcing: verbose='$verbose', name='$name'"
(Ja, ich weiß, dass der reguläre Ausdruck nicht so stark ist; er ist nur ein Platzhalter.) Leider scheint die Quelle mit den folgenden Dokumenten nicht gut zu spielen:
./script.sh: line 1: source: filename argument required
source: usage: source filename [arguments]
After sourcing: verbose='', name=''
Natürlich könnte ich eine beliebige Anzahl von Dingen tun, um Konfigurationsdaten aus einer Datei zu erhalten, und das ist wahrscheinlich sowieso sicherer.
Aber ich habe immer noch diesen Juckreiz; Ich möchte herausfinden, ob das, was ich versucht habe, funktionieren kann. Irgendwelche Vorschläge?
while IFS== read -r var value; do case $var in |*[!0-9A-Z_a-z]*) complain;; *) eval "config_$var=\$value";; esac; done <config
(Warnung: getippt in meinem Browser, ! Test es ) Vergessen Sie nicht , keine Variablen zu erlauben den Import wie PATH
, IFS
... Ein Präfix wie config_
ist ein sicherer Ansatz.
/dev/fd/[num]
. Dies zu emulieren ist einfach : 3<<HEREDOC . /dev/fd/3\n*file contents*\nHEREDOC\n
. Prozess Substitution in der Regel ist ein Rohr, während Heredocs sind in der Regel die Schale TMPFILES Löschungen vor Gabe sie aus - so dass sie nur als Deskriptoren vorhanden sind . in dash
ihnen sind Rohre. Der andere große Unterschied ist, dass Sie fd [num]
für Heredocs angeben können .
<<EOF
) wie eine normale Eingabeweiterleitung (< file
)source < file
funktioniert und nicht funktioniert - essource
muss ein Dateinamenargument vorhanden sein. Daher benötigen Sie process substitution (<(command)
), das wie ein Dateinamenargument aussieht.