flawopen.com/Command Injection/os.system()
It's risky whenever any part of the command string includes untrusted input — os.system() always runs its argument through a shell, with no way to opt out.
os.system(f"ping -c 1 {host}")subprocess.run( ["ping", "-c", "1", host] )
Unlike subprocess.run(), which can be called without a shell, os.system() is defined to always pass its string to the platform's shell (/bin/sh on Unix). There's no argument-list form — any call to it that includes untrusted input needs the same shell-metacharacter awareness as shell=True, but without the option to remove the shell from the equation.
Yes, when the entire command string is a fixed, hardcoded constant with no interpolated values at all. The moment any part of it is dynamic and traces back to outside input, it needs the subprocess module's list-argument form instead.