Back to skill

Security audit

Phy Git Branch Janitor

Security checks for vulnerabilities and agentic risk

Overview

The skill fits its Git branch-cleanup purpose, but it needs review because it can generate copy-paste delete commands that are unsafe for unusual branch names.

Review generated commands before running them, especially in repositories with branches created by other people. Do not paste cleanup commands blindly; branch names should be validated and shell-quoted, and remote deletions or force-deletes should be confirmed manually.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:173
Finding
Shell Command Injection Through Unquoted Git Branch Names<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 173–179 **Vulnerability Type**: Shell command injection in generated cleanup commands **Risk Level**: High ### Vulnerable Code ```bash # Delete merged local branches git branch -d feat/add-login feat/fix-typo chore/update-deps # Delete merged remote branches git push origin --delete feat/add-login feat/fix-typo chore/update-deps ``` The skill instructs the agent to replace the example branch names with branch names discovered from the repository and present the result as a copy-paste shell command. These repository-controlled names are inserted directly into shell command text without validation or shell-safe quoting. ### Technical Analysis Git reference names cannot contain certain characters, but they can contain several characters that have special meaning when included literally in a shell command. A maliciously constructed branch name containing a command separator or command-substitution syntax can alter the generated command's structure. For example, if a repository contains a branch whose name incorporates a semicolon followed by a command, inserting that name verbatim into the documented command causes the shell to treat the remainder as a separate command. This differs from ordinary shell variable expansion: the branch name becomes literal source text in a newly generated command before the user's shell parses it. The risk applies to both local deletion commands and remote deletion commands. Similar unsafe command-generation patterns are repeated in the report template, including the cleanup examples around lines 216–220 and 240–241. The use of `git branch -d` limits accidental deletion of unmerged branches, but it does not prevent the shell from interpreting metacharacters before Git processes its arguments. The optional PR status check also does not sanitize branch names for subsequent shell output. ### Attack Path 1. An attacker creates a branch with a valid Git refer ...[truncated 1486 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Do not concatenate raw branch names into shell source text.** Prefer executing Git through an API that accepts an argument array, so branch names never pass through shell parsing. 2. **Validate every discovered reference before use.** Apply `git check-ref-format --branch` and reject any branch that does not satisfy the expected branch-name rules. Validation alone should not replace safe argument handling. 3. **Apply robust shell escaping when copy-paste commands are required.** Quote every branch name with a proven implementation such as Python's `shlex.quote`: ```python import shlex command = "git branch -d -- " + " ".join( shlex.quote(branch) for branch in branches ) ``` 4. **Use option delimiters where supported.** Place `--` before branch-name arguments to prevent a branch name from being interpreted as a command-line option: ```bash git branch -d -- 'branch-name' ``` 5. **Treat remote deletion separately.** Construct fully qualified deletion refspecs through an argument array rather than interpolating names into a shell command. Validate that each destination begins with the expected `refs/heads/` namespace. 6. **Refuse executable output for suspicious names.** If a branch contains shell metacharacters or cannot be represented safely, display it only as escaped diagnostic data and require manual handling. 7. **Require explicit confirmation before destructive operations.** Clearly separate audit output from executable deletion commands, and never characterize generated commands as automatically safe solely because branches appear merged. 8. **Add adversarial tests.** Test command rendering with branch names containing semicolons, dollar signs, parentheses, quotes, newlines where accepted, leading option-like characters, Unicode, and other unusual but valid reference-name characters. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Vague Triggers

Medium
Confidence
91% confidence
Finding
The description advertises triggers such as "clean up branches," "stale branches," and especially "delete old branches," which are fairly broad natural-language phrases and could overlap with ordinary conversation about Git maintenance. The file does not provide exclusion conditions or negative examples to clarify when the skill should not activate.

Vague Triggers

Medium
Confidence
90% confidence
Finding
Several listed triggers, including "branch cleanup," "stale branches," and "which branches can I delete," are understandable but still broad enough to match common repo discussions rather than an intentional skill invocation. The section does not define required context, exclusions, or a canonical invocation format beyond one slash-command option.

Static analysis

No suspicious patterns detected.