python.lang.security.audit.dangerous-spawn-process.dangerous-spawn-process

Community Favorite
profile photo of returntocorpreturntocorp
Author
45,436
Download Count*

Found dynamic content when spawning a process. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Ensure no external data reaches here.

Run Locally

Run in CI

Defintion

rules:
  - id: dangerous-spawn-process
    message: Found dynamic content when spawning a process. This is dangerous if
      external data can reach this function call because it allows a malicious
      actor to execute commands. Ensure no external data reaches here.
    metadata:
      source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html
      cwe: "CWE-78: Improper Neutralization of Special Elements used in an OS Command
        ('OS Command Injection')"
      owasp: "A1: Injection"
      asvs:
        section: "V5: Validation, Sanitization and Encoding Verification Requirements"
        control_id: 5.3.8 OS Command Injection
        control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements
        version: "4"
      category: security
      technology:
        - python
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
    languages:
      - python
    severity: ERROR
    pattern-either:
      - patterns:
          - pattern-not: os.$METHOD($MODE, "...", ...)
          - pattern: os.$METHOD(...)
          - metavariable-regex:
              metavariable: $METHOD
              regex: (spawnl|spawnle|spawnlp|spawnlpe|spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp|startfile)
      - patterns:
          - pattern-not: os.$METHOD($MODE, "...", ["...","...",...], ...)
          - pattern: os.$METHOD($MODE, $BASH, ["-c",$CMD,...],...)
          - metavariable-regex:
              metavariable: $METHOD
              regex: (spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp)
          - metavariable-regex:
              metavariable: $BASH
              regex: (.*)(sh|bash|ksh|csh|tcsh|zsh)
      - patterns:
          - pattern-not: os.$METHOD($MODE, "...", "...", "...", ...)
          - pattern: os.$METHOD($MODE, $BASH, "-c", $CMD,...)
          - metavariable-regex:
              metavariable: $METHOD
              regex: (spawnl|spawnle|spawnlp|spawnlpe)
          - metavariable-regex:
              metavariable: $BASH
              regex: (.*)(sh|bash|ksh|csh|tcsh|zsh)

Examples

dangerous-spawn-process.py

import os
import shlex
from somewhere import something

# ok:dangerous-spawn-process
os.spawnlp(os.P_WAIT, "ls")

# ok:dangerous-spawn-process
os.spawnlpe(os.P_WAIT, "ls")

# ok:dangerous-spawn-process
os.spawnv(os.P_WAIT, "/bin/ls")

# ok:dangerous-spawn-process
os.spawnve(os.P_WAIT, "/bin/ls", ["-a"], os.environ)

# ruleid:dangerous-spawn-process
os.spawnlp(os.P_WAIT, something())

# ruleid:dangerous-spawn-process
os.spawnlpe(os.P_WAIT, something())

# ruleid:dangerous-spawn-process
os.spawnv(os.P_WAIT, something())

# ruleid:dangerous-spawn-process
os.spawnve(os.P_WAIT, something(), ["-a"], os.environ)

# ruleid:dangerous-spawn-process
os.spawnve(os.P_WAIT, "/bin/bash", ["-c", something()], os.environ)

# ruleid:dangerous-spawn-process
os.spawnl(os.P_WAIT, "/bin/bash", "-c", something())

def run_payload(shell_command: str) -> None:
    args = shlex.split(shell_command)
    path = args[0]
    # ruleid:dangerous-spawn-process
    pid = os.posix_spawn(path, args, os.environ)
    os.waitpid(pid, 0)