Arbitrary OS command injection vulnerabilities are more likely when a shell is spawned rather than a new process, indeed shell meta-chars can be used (when parameters are user-controlled for instance) to inject OS commands.

Why is this an issue?

When a shell interpreter is used to execute OS commands, shell meta-characters in user-controlled input can be exploited to inject additional commands. Functions that spawn a shell process—such as os.system() in Python, exec() in JavaScript, or Runtime.exec() in Java—create an attack surface for OS command injection that would not exist if a new process were spawned directly without a shell. This is especially dangerous when the command name or parameters are derived from user input.

What is the potential impact?

An attacker who can control the OS command name or its parameters can inject arbitrary OS commands that execute with the privileges of the application. This can lead to complete system compromise, unauthorized data access, or the installation of malware on the host.

How to fix it in Python Standard Library

Code examples

Noncompliant code example

subprocess.run(cmd, shell=True)  # Noncompliant
subprocess.Popen(cmd, shell=True)  # Noncompliant
os.system(cmd)  # Noncompliant: a shell is always spawned

Compliant solution

# shell=False by default; no shell is spawned
subprocess.run(cmd)
subprocess.Popen(cmd)

Resources

Standards