Security Python active any

Subprocess execution avoids shell injection paths

python-sec-001

Intent

Python subprocess boundaries are command-injection boundaries. User-influenced commands should not flow through shell=True or string-concatenated command lines.

Applicability

Applies when the code calls subprocess, os.system, asyncio.create_subprocess_*, or wrappers around them. Return unknown when input provenance is not visible.

What to inspect

Subprocess calls, command arrays, shell=True, os.system, and formatted shell strings.

Pass criteria

Commands are passed as argument lists, and executables and arguments are fixed or validated from a narrow allowlist.

Fail criteria

shell=True is used with external input, command strings are built from untrusted values, or os.system executes externally influenced content.

Do not flag

Constant command lists with no external input. Test code exercising subprocess wrappers.

Confidence guidance

HIGH when the injection path is directly visible. MEDIUM when provenance is inferred. LOW when the source is unclear.

Remediation

Use argument arrays with shell=False, and allowlist command choices and arguments explicitly.

Pass example

subprocess.run(["git", "checkout", validated_branch], shell=False, check=True)

Fail example

os.system(f"git checkout {user_input}")