Back to skill

Security audit

Post Merge Rename

Security checks for vulnerabilities and agentic risk

Overview

This skill is a Git branch-renaming helper, but it can delete remote branch names despite repeatedly saying it never deletes branches.

Review before installing or running in shared repositories. Use only on repos where you are comfortable with automatic local branch renames, pushing new remote branch names, and deleting old remote branch refs; prefer --dry-run first and avoid use in production automation until the deletion behavior is made explicit and verified.

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

Warning
Location
post-merge-rename.sh:88
Finding

Remote Branch Deletion Proceeds Despite Failed Preservation Operations

Content
View full analysis

Vulnerability Details

File Location: post-merge-rename.sh, lines 88-95
Vulnerability Type: Unchecked failures before destructive Git operation
Risk Level: Medium

bash
else
  echo "  Renaming: $trimmed -> $new_name"

  # Rename local
  git branch -m "$trimmed" "$new_name" 2>/dev/null || true

  # Push new name to remote
  git push origin "$new_name" 2>/dev/null || true

  # Remove old name from remote
  git push origin --delete "$trimmed" 2>/dev/null || true
fi

Technical Analysis

The script suppresses errors from the local branch rename and the push of the replacement branch by appending || true. It then unconditionally attempts to delete the original branch from origin.

Consequently, failure to rename the local branch or publish the replacement remote reference does not stop the destructive deletion step. Although set -euo pipefail is enabled, the explicit || true expressions negate its failure-handling protection. Redirecting standard error to /dev/null also prevents the user from seeing why preservation failed.

This behavior contradicts the claim in README.md line 10 and the script comments that branches are never deleted. SKILL.md does disclose deletion of the old remote branch, but the inconsistent documentation may cause operators to underestimate the operation's destructive nature.

Attack Path

  1. A merged local branch is selected for processing.
  2. The local rename or push of the dated replacement fails, for example because of a name collision, permissions, a remote policy, or an inconsistent repository state.
  3. The failure is suppressed with 2>/dev/null || true.
  4. The script continues to git push origin --delete "$trimmed".
  5. If the caller has deletion permission, the original remote branch reference is removed without confirmation that an equivalent replacement was successfully published.

An attacker who can influence repository state or remote ...[truncated 564 chars]

Remediation
View remediation

Remediation Suggestions

Remove || true from the local rename and replacement push, and do not discard their diagnostics. Permit deletion only after all preservation steps have succeeded.

Before deleting the old remote branch:

  1. Record the original branch commit with git rev-parse.
  2. Rename the local branch and require success.
  3. Push the replacement branch using an explicit refspec.
  4. Query the new remote reference and verify that it resolves to the expected commit.
  5. Delete the old remote reference only after successful verification.
  6. Exit with a nonzero status and retain the old branch whenever any step fails.
  7. Consider requiring explicit confirmation or a separate flag for remote deletion.
  8. Update all documentation to clearly state that the old remote branch name is deleted after successful preservation.

Example control flow:

bash
original_commit=$(git rev-parse "$trimmed") || exit 1
git branch -m "$trimmed" "$new_name" || exit 1
git push origin "refs/heads/$new_name:refs/heads/$new_name" || exit 1

remote_commit=$(git ls-remote --heads origin "refs/heads/$new_name" |
  awk '{print $1}')

if [[ "$remote_commit" != "$original_commit" ]]; then
  echo "Error: replacement remote branch was not verified." >&2
  exit 1
fi

git push origin --delete "$trimmed" || exit 1
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill is presented as a history-preserving branch rename utility, but its documented behavior also includes remote-modifying actions: fetching/pruning, pushing renamed branches, and deleting the old remote branch name. That mismatch is dangerous because users or automation may invoke it expecting a local rename-only operation, while it can irreversibly alter shared remote state and remove a branch ref relied upon by collaborators or tooling.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation says 'We never delete branches. We rename them,' yet later states it deletes the old branch name from origin. Even if the implementation is meant as a rename workflow, deleting the original remote ref is still a destructive operation from the user's perspective and can cause loss of discoverability, break scripts, and disrupt collaborators who still reference the old branch name.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Directly contradictory inline documentation undermines informed consent and safe use of the skill. In an automation or DevOps context, operators may trust the non-deletion claim and run the skill in production repositories, only to trigger remote branch deletion that affects team workflows and retention expectations.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The inline comment says 'Never deletes branches. Only renames.', but the script later deletes the old remote branch after pushing the new one. This mismatch is dangerous because users and automation may trust the documentation and run the skill in environments where remote branch deletion is sensitive, causing unintended destructive changes.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script’s stated behavior is to preserve history by renaming merged branches, but it also executes git push origin --delete "$trimmed", which removes the old remote branch reference. While Git commits may still exist, deleting the remote branch name can disrupt workflows, break tooling or links that depend on the branch name, and violate operator expectations created by the documentation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README explicitly promotes automatic post-merge branch renaming but does not warn users that it mutates repository state or suggest confirmation, dry-run, or scope limitations. In an agent-executed or automation context, undocumented automatic branch mutation can cause unexpected branch name changes, break scripts or workflows that depend on stable names, and make recovery harder if users did not anticipate the behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation mentions deleting the old branch name from origin without a clear warning that this is a potentially disruptive remote action. In the context of a git skill that may be run automatically after merges, insufficient warning increases the chance of accidental execution against shared repositories, causing unexpected branch-ref removal and downstream CI or tooling failures.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.