Supposons que vous utilisez shell=False et que vous fournissez la commande sous forme de liste. Et qu'un utilisateur malveillant essaie d'injecter une commande 'rm'. Vous verrez que 'rm' sera interprété comme un argument et que 'ls' essaiera de trouver un fichier appelé 'rm'.
>>> subprocess.run(['ls','-ld','/home','rm','/etc/passwd'])
ls: rm: No such file or directory
-rw-r--r-- 1 root root 1172 May 28 2020 /etc/passwd
drwxr-xr-x 2 root root 4096 May 29 2020 /home
CompletedProcess(args=['ls', '-ld', '/home', 'rm', '/etc/passwd'], returncode=1)
shell=False n'est pas une sécurité par défaut, si vous ne contrôlez pas correctement l'entrée. Vous pouvez toujours exécuter des commandes dangereuses.
>>> subprocess.run(['rm','-rf','/home'])
CompletedProcess(args=['rm', '-rf', '/home'], returncode=0)
>>> subprocess.run(['ls','-ld','/home'])
ls: /home: No such file or directory
CompletedProcess(args=['ls', '-ld', '/home'], returncode=1)
>>>
J'écris la plupart de mes applications dans des environnements de conteneurs, je sais quel shell est invoqué et je ne prends aucune entrée utilisateur.
Ainsi, dans mon cas d'utilisation, je ne vois aucun risque de sécurité. Et il est beaucoup plus facile de créer de longues chaînes de commandes. J'espère que je ne me trompe pas.
49 votes
La première commande est incorrecte :
-l
est transmis à/bin/sh
(le shell) au lieu dels
programme sous Unix sishell=True
. L'argument chaîne doit être utilisé avecshell=True
dans la plupart des cas, au lieu d'une liste.3 votes
Re "le processus est directement lancé" : Quoi ?
21 votes
L'affirmation "Les deux fonctionnent" à propos de ces deux appels est incorrecte et trompeuse. Les appels fonctionnent différemment. Il suffit de passer de
shell=True
aFalse
et vice versa est une erreur. De docs : "Sur POSIX avec shell=True, (...) Si args est une séquence, le premier élément spécifie la chaîne de commande, et tous les éléments supplémentaires seront traités comme des arguments supplémentaires pour le shell lui-même.". Sous Windows, il y a conversion automatique ce qui pourrait être indésirable.0 votes
Voir aussi stackoverflow.com/q/59641747/874188
1 votes
Note utile : vous pouvez alimenter une liste à call/Popen, mais il ignorera silencieusement tout sauf le premier élément de la liste. Python 3.5/Linux.