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)
Summary
commitizen uses
subprocess.Popen(cmd, shell=True)incommitizen/cmd.pyto execute all git commands. Multiple functions incommitizen/git.pyconstruct shell commands by interpolating values via f-strings without escaping.Affected Code
commitizen/cmd.pylines 41-43:commitizen/git.pyline 173:commitizen/git.pyline 167:commitizen/git.pyline 177:Attack Vector
An attacker poisons
pyproject.toml(e.g., via PR) with:When CI/CD runs
cz bump, the shell interprets the injected command.Impact
Suggested Fix
Replace
shell=Truewith list-based subprocess, or useshlex.quote():Reported by: Tom Chen (hypery11@gmail.com)