flawopen.com/Command Injection/Python subprocess

Is Python's subprocess.run(shell=True) safe?

Reference page — draft, pending review
Short answer

Not if any part of the command string includes untrusted input. shell=True runs the command through an actual shell, which means shell metacharacters (;, |, &&, backticks) in the input can chain in additional commands.

VULNERABLE
# filename from user upload
subprocess.run(
  f"convert {filename} out.png",
  shell=True
)
FIXED
# no shell, args passed as a list
subprocess.run(
  ["convert", filename, "out.png"]
)

Why the fix works

Without shell=True, subprocess.run() executes the program directly with the given argument list — there's no shell parsing the string, so characters like ; or | in filename are passed literally as part of that one argument, never interpreted as command separators.

FAQ

Is shlex.quote() a good alternative if I must use shell=True?

It's a real mitigation but a weaker one than avoiding the shell entirely — it requires quoting every single interpolated value correctly, with no structural guarantee if one is missed. Avoiding shell=True is the more robust default.

Does this apply the same way to os.system()?

Yes — os.system() always runs through a shell, so it carries this risk unconditionally whenever it includes untrusted input.

References