T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/audit_repo.py:384
- Finding
- Shell Command Injection Through Attacker-Controlled Git Branch Names## Vulnerability Details **File Location**: `scripts/audit_repo.py`, lines 384–395 **Vulnerability Type**: Shell command injection in generated cleanup script **Risk Level**: High ### Vulnerable Code ```python if branch_findings.get("merged"): lines.append("# === Delete merged branches ===") for b in branch_findings["merged"]: lines.append(f'echo "Deleting merged branch: {b["name"]}"') lines.append(f'git branch {delete_flag} "{b["name"]}"') lines.append("") if branch_findings.get("stale"): lines.append("# === Delete stale branches (review carefully!) ===") for b in branch_findings["stale"]: lines.append(f'# Stale {b["days_old"]} days, last: {b["last_subject"][:50]}') if force_delete: lines.append(f'git branch -D "{b["name"]}"') else: lines.append(f'# git branch -D "{b["name"]}" # Uncomment after review') ``` ### Technical Analysis Branch names are read from the repository and interpolated directly into shell commands. The generated commands enclose branch names in double quotes, but double quotes do not disable shell command substitution through constructs such as `$()` or backticks. Consequently, a branch name containing shell metacharacters accepted by Git can introduce executable shell expressions into the generated cleanup script. The expressions are evaluated when the user executes that script. The vulnerable values are used both in an `echo` command and in branch-deletion commands. Although `--fix` prints rather than automatically executes the cleanup script, the documented workflow explicitly directs users to save, review, and execute it. This creates a direct path from untrusted repository metadata to local command execution. ### Attack Path 1. An attacker creates or supplies a Git repository containing a maliciously named stale or merged branch. 2. The victim runs the audit tool against that repository with ...[truncated 902 chars]
- Remediation
- ## Remediation Suggestions - Apply robust shell escaping to every repository-derived value using `shlex.quote()`. - Insert the Git end-of-options marker before branch names, for example: `git branch -d -- "$branch"`. - Validate branch names and reject values containing unsafe or unexpected shell syntax. - Prefer generating a structured data file and using a trusted Python cleanup program that invokes Git through `subprocess.run()` with an argument list and `shell=False`. - If shell output must be generated, assign safely quoted values to variables and never interpolate raw repository metadata into executable shell source. - Add automated tests using branch names containing `$()`, backticks, dollar signs, parentheses, and other shell-significant characters. - Clearly warn users that cleanup output generated from an untrusted repository must not be executed without validation.
