Skip to content

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

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)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions