Skip to content

Security: Command injection via shell=True in git command execution (CWE-78) #1918

@hypery11

Description

@hypery11

Summary

commitizen uses subprocess.Popen(cmd, shell=True) in commitizen/cmd.py to execute all git commands. Multiple functions in commitizen/git.py construct shell commands by interpolating values via f-strings without escaping.

Affected Code

commitizen/cmd.py lines 41-43:

process = subprocess.Popen(cmd, shell=True, ...)

commitizen/git.py line 173:

return cmd.run(f'git tag {option} {tag} -m "{msg or tag}"')

commitizen/git.py line 167:

return cmd.run(f"git tag {tag}")

commitizen/git.py line 177:

return cmd.run(f"git add {' '.join(args)}")

Attack Vector

An attacker poisons pyproject.toml (e.g., via PR) with:

[tool.commitizen]
annotated_tag = true
annotated_tag_message = 'Release" && malicious_command && echo "'

When CI/CD runs cz bump, the shell interprets the injected command.

Impact

  • Arbitrary command execution in CI/CD pipelines
  • CVSS 3.1: 7.8 (High)
  • Similar to CVE-2026-33718 (OpenHands command injection via git operations)

Suggested Fix

Replace shell=True with list-based subprocess, or use shlex.quote():

subprocess.run(["git", "tag", option, tag, "-m", msg or tag])

Reported by: Tom Chen (hypery11@gmail.com)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions