Back to skill

Security audit

Git Deployer

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but it needs Review because its deploy script can overwrite Git history and uses unsafe temporary Git-clone handling.

Review this skill before installing. Use it only with trusted site directories and repositories you are willing to overwrite, and avoid shared or protected branches. Safer operation would require a private unpredictable temp directory, rejecting .git in the site input, disabling Git hooks during automated commits, validating the remote and branch, and replacing unconditional --force with confirmation or --force-with-lease.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/deploy.sh:48
Finding

Git Metadata Can Be Deleted or Replaced During Site Synchronization

Content
View full analysis

Vulnerability Details

File Location: scripts/deploy.sh, lines 48-66
Vulnerability Type: Unsafe synchronization into a Git worktree
Risk Level: High

Vulnerable Code

bash
# Copy files (rsync-like behavior: mirror contents)
echo "[2/5] Copying site files to clone..."
rsync -av --delete "$SITE_PATH/" "$TMP_CLONE/"

# Stage all changes
echo "[3/5] Staging files..."
git add -A

# Check if there are changes to commit
if git diff --staged --quiet; then
    echo "No changes to commit — repository is up to date."
    echo "Nothing to push."
    exit 0
fi

# Commit
echo "[4/5] Committing..."
git commit -m "$COMMIT_MSG"

Technical Analysis

The destination directory is an active Git worktree containing a security-sensitive .git directory. The rsync command mirrors the entire source directory into that worktree with --delete, but it does not exclude .git.

If the source does not contain .git, --delete can remove the destination's Git metadata, causing subsequent Git commands to fail. More seriously, if the source contains an attacker-controlled .git directory, its repository configuration and hooks can be copied into the destination. The later git commit operation can execute a malicious pre-commit, prepare-commit-msg, commit-msg, or related Git hook.

Quoting SITE_PATH prevents shell argument injection but does not prevent the transfer of malicious repository metadata.

Attack Path

  1. An attacker gains control over, or influences, the directory supplied as site_path. This may occur when deploying generated or externally supplied site artifacts.
  2. The attacker adds a crafted .git directory to the site content.
  3. The crafted metadata includes an executable hook such as .git/hooks/pre-commit.
  4. The script executes:
    bash
    rsync -av --delete "$SITE_PATH/" "$TMP_CLONE/"
    
    and copies the malicious Git metadata into the deployme ...[truncated 929 chars]
Remediation
View remediation

Remediation Suggestions

  • Explicitly exclude Git metadata from synchronization:
    bash
    rsync -av --delete --exclude='/.git/' "$SITE_PATH/" "$TMP_CLONE/"
    
  • Reject source directories containing a top-level .git file or directory before synchronization:
    bash
    if [[ -e "$SITE_PATH/.git" ]]; then
        echo "ERROR: Site path must not contain Git metadata" >&2
        exit 1
    fi
    
  • Verify that the destination remains the expected Git worktree after synchronization:
    bash
    git -C "$TMP_CLONE" rev-parse --is-inside-work-tree
    
  • Disable hooks for deployment Git operations by using an empty, trusted hooks directory:
    bash
    git -c core.hooksPath=/dev/null commit -m "$COMMIT_MSG"
    
  • Treat generated or externally supplied deployment artifacts as untrusted and validate their file types and paths before copying.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/deploy.sh:24
Finding

Predictable Shared Temporary Clone Directory Enables Repository and Tooling Hijacking

Content
View full analysis

Vulnerability Details

File Location: scripts/deploy.sh, lines 24-45
Vulnerability Type: Predictable and unvalidated temporary directory
Risk Level: High

Vulnerable Code

bash
# Extract repo name from URL for /tmp directory
REPO_NAME=$(basename "$REMOTE_URL" .git)
TMP_CLONE="/tmp/$REPO_NAME"
TIMESTAMP=$(date -u "+%Y-%m-%d %H:%M:%S")
COMMIT_MSG="Deploy: $TIMESTAMP UTC"

echo "=== git-deployer ==="
echo "Site path: $SITE_PATH"
echo "Remote:    $REMOTE_URL"
echo "Branch:    $BRANCH"
echo "Timestamp: $TIMESTAMP"
echo ""

# Clone or init
if [[ -d "$TMP_CLONE" ]]; then
    echo "[1/5] Clone exists at $TMP_CLONE — pulling latest..."
    cd "$TMP_CLONE"
    git fetch origin
    git checkout "$BRANCH" || git checkout -b "$BRANCH"
    git pull origin "$BRANCH"
else
    echo "[1/5] Cloning fresh repo..."
    git clone "$REMOTE_URL" "$TMP_CLONE"
    cd "$TMP_CLONE"
    git checkout "$BRANCH" 2>/dev/null || git checkout -b "$BRANCH"
fi

Technical Analysis

The temporary clone path is predictably constructed from only the remote repository basename. The script trusts any existing directory at that path without validating:

  • Its owner or permissions
  • Whether it is a symbolic link
  • Whether it is a valid Git worktree
  • Whether its configured origin matches REMOTE_URL
  • Whether its Git configuration and hooks are trusted

Repositories hosted by different users or services can share the same basename and therefore collide at the same /tmp path. An attacker with local access can also pre-create the expected directory as a malicious repository or as a symbolic link.

Git operations are performed before the site synchronization step. A malicious pre-created repository can therefore influence git fetch, git checkout, and git pull. Dangerous repository-local configuration can specify external commands, including an attacker-controlled SSH command, credential help ...[truncated 1787 chars]

Remediation
View remediation

Remediation Suggestions

  • Create a fresh, unpredictable directory with restrictive permissions for every deployment:
    bash
    umask 077
    TMP_CLONE=$(mktemp -d "${TMPDIR:-/tmp}/git-deployer.XXXXXXXX")
    
  • Register a cleanup handler unless preserving the clone is an explicit requirement:
    bash
    trap 'rm -rf -- "$TMP_CLONE"' EXIT
    
  • Do not reuse a directory based only on a repository basename.
  • If reuse is required, store clones in a private directory owned by the deployment user and derive a collision-resistant identifier from the complete canonical remote URL.
  • Reject symbolic links and verify directory ownership and permissions before entering any reused directory.
  • Validate repository identity before performing network or checkout operations:
    bash
    actual_remote=$(git -C "$TMP_CLONE" remote get-url origin)
    [[ "$actual_remote" == "$REMOTE_URL" ]] || exit 1
    
  • Avoid trusting repository-local execution configuration. Use a trusted empty hooks directory and sanitize dangerous Git configuration for automated deployment operations.
  • Use git -C "$TMP_CLONE" instead of changing the process working directory, and validate that TMP_CLONE resolves beneath the expected private parent directory.
Vulnerability Patterns
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • 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)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
91% confidence
Finding

The BRANCH parameter is user-controlled and is used in a destructive git push -u origin "$BRANCH" --force, allowing an operator or upstream caller to force-overwrite any branch name supplied to the script. While the branch is shell-quoted, preventing command injection, the real issue is dangerous parameter-driven behavior: a wrong or attacker-influenced branch value can cause unauthorized history rewrites on sensitive branches.

Content

Scanner excerpt · scripts/deploy.sh (reported line 73)May include surrounding context.

sh
# Force push
echo "[5/5] Force-pushing to $BRANCH..."
git push -u origin "$BRANCH" --force

echo ""
echo "=== Deploy Complete ==="

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script always performs git push --force, which rewrites remote branch history and can delete commits on the destination branch without any confirmation or safety check. In a deployment skill, this is especially risky because a mistaken branch, reused repository, or concurrent updates can permanently overwrite valid remote content and disrupt recovery.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.