Back to skill

Security audit

Mercurial to Git Converter

Security checks for vulnerabilities and agentic risk

Overview

This Mercurial-to-Git conversion skill is purpose-aligned, but it can automatically install or run unverified external tooling and one script can delete an existing target directory without confirmation.

Install only if you are comfortable with scripts that may change system packages, download hg-fast-export from GitHub, leave a copy under your home directory, and write or delete destination repository paths. Use a fresh empty target directory, back up important data, and prefer preinstalling a trusted hg-fast-export version before running the scripts.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/hg-to-git.sh:56
Finding
Unpinned Remote Dependency Is Downloaded and Executed<![CDATA[ ## Vulnerability Details **File Location**: `scripts/hg-to-git.sh`, lines 56-73 and 97-100 **Vulnerability Type**: Remote execution of an unverified, mutable dependency **Risk Level**: High ### Vulnerable Code ```bash # If still not found, clone from source if ! command -v hg-fast-export &> /dev/null && ! command -v hg-fast-export.sh &> /dev/null; then FAST_EXPORT_DIR="${HOME}/.local/share/hg-fast-export" if [ ! -d "$FAST_EXPORT_DIR" ]; then mkdir -p "$(dirname "$FAST_EXPORT_DIR")" git clone https://github.com/frej/fast-export.git "$FAST_EXPORT_DIR" fi export PATH="$FAST_EXPORT_DIR:$PATH" fi # Determine fast-export command if command -v hg-fast-export &> /dev/null; then FAST_EXPORT_CMD="hg-fast-export" elif command -v hg-fast-export.sh &> /dev/null; then FAST_EXPORT_CMD="hg-fast-export.sh" elif [ -f "${HOME}/.local/share/hg-fast-export/hg-fast-export.sh" ]; then FAST_EXPORT_CMD="${HOME}/.local/share/hg-fast-export/hg-fast-export.sh" ``` ```bash # Perform conversion echo "" echo "Converting... (this may take a while for large repos)" "$FAST_EXPORT_CMD" -r "$HG_REPO" --force ``` ### Technical Analysis When `hg-fast-export` is unavailable, the script clones the current contents of an external GitHub repository and subsequently executes `hg-fast-export.sh`. The clone is not pinned to a reviewed commit or immutable release, and no checksum or cryptographic signature is verified. Consequently, the code executed during conversion can differ from the code that existed when this Skill was audited. Compromise of the upstream repository, its default branch, its maintainers, or the network trust chain could cause attacker-controlled code to be placed in the installation directory and executed. The script also trusts an existing `${HOME}/.local/share/hg-fast-export` directory without validating its ownership, contents, or integrity. An attacker who can prepopulate that location may be able to influence the executa ...[truncated 1207 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not automatically download and execute code during repository conversion. Require users to install the dependency explicitly. 2. If automatic installation is retained, pin the dependency to a reviewed, immutable commit hash or signed release rather than the current default branch. 3. Verify a published cryptographic checksum or trusted signature before executing the dependency. 4. Download into a newly created, permission-restricted directory and verify that the destination is owned by the current user and is not a symbolic link. 5. Invoke the verified executable by its canonical absolute path rather than adding its directory to `PATH`. 6. Record the approved dependency version and hash in the project documentation. 7. Require explicit user consent before any dependency download or privileged package-manager operation. ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/hg-to-git-large.sh:50
Finding
Large-Repository Converter Downloads and Executes an Unpinned Remote Script<![CDATA[ ## Vulnerability Details **File Location**: `scripts/hg-to-git-large.sh`, lines 50-57 and 75-82 **Vulnerability Type**: Remote execution of an unverified, mutable dependency **Risk Level**: High ### Vulnerable Code ```bash else FAST_EXPORT_DIR="${HOME}/.local/share/hg-fast-export" if [ ! -d "$FAST_EXPORT_DIR" ]; then echo "Installing hg-fast-export..." mkdir -p "$(dirname "$FAST_EXPORT_DIR")" git clone --depth 1 https://github.com/frej/fast-export.git "$FAST_EXPORT_DIR" fi FAST_EXPORT_CMD="${FAST_EXPORT_DIR}/hg-fast-export.sh" fi ``` ```bash # Run conversion with feedback "$FAST_EXPORT_CMD" -r "$HG_REPO" --force 2>&1 | while read line; do if [[ $line == *"revision"* ]]; then echo -n "." else echo "$line" fi done ``` ### Technical Analysis The large-repository converter performs a shallow clone of the current default branch of an external repository and immediately treats a script from that clone as executable conversion tooling. A shallow clone does not provide integrity or immutability: it still retrieves whichever commit the remote default branch references at execution time. No approved commit identifier, release version, checksum, or signature is checked. The script also accepts an already existing `${HOME}/.local/share/hg-fast-export` directory without validating its ownership or contents. This behavior creates a remote payload execution channel in which the effective code can change after the Skill package has been reviewed. ### Attack Path 1. A user runs `scripts/hg-to-git-large.sh` without `hg-fast-export` available in `PATH`. 2. The script clones the external dependency's current default branch, or reuses an existing local dependency directory. 3. The upstream repository or local directory contains an attacker-modified `hg-fast-export.sh`. 4. The script performs no integrity verification. 5. The attacker-controlled script is executed with the source repository path as ...[truncated 518 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic remote installation and fail with clear instructions when the dependency is absent. 2. Alternatively, pin the clone to a reviewed commit and verify its checksum or trusted signature before execution. 3. Do not rely on `--depth 1` as a security control; explicitly check out and validate the approved commit. 4. Validate the ownership, permissions, canonical path, and contents of any existing dependency directory. 5. Store verified dependencies in a permission-restricted location and invoke them through a canonical absolute path. 6. Document the exact supported dependency version and provide a reproducible installation procedure. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/hg-to-git-large.sh:60
Finding
Unconditional Recursive Deletion of a User-Supplied Target Directory<![CDATA[ ## Vulnerability Details **File Location**: `scripts/hg-to-git-large.sh`, lines 60-68 **Vulnerability Type**: Unsafe destructive filesystem operation **Risk Level**: High ### Vulnerable Code ```bash # Create git repo if [ -d "$GIT_REPO" ]; then echo "Removing existing $GIT_REPO..." rm -rf "$GIT_REPO" fi mkdir -p "$GIT_REPO" cd "$GIT_REPO" git init ``` ### Technical Analysis `GIT_REPO` is taken directly from the second command-line argument or derived from the source path. If that path names an existing directory, the script recursively deletes it without confirmation, without requiring an explicit force option, and without checking whether the directory is a safe conversion target. Quoting prevents shell word splitting but does not make the deletion safe. A valid absolute path such as the user's home directory, an unrelated project, or another important writable directory will still be recursively removed. The script does not canonicalize the target or reject dangerous values such as `/`, `$HOME`, the source repository, or a parent of the source repository. ### Attack Path 1. A user or automation system supplies an existing directory as the second argument to `hg-to-git-large.sh`. 2. The supplied value passes the only relevant test because it is a directory. 3. The script reaches the repository-creation stage without requesting confirmation. 4. `rm -rf "$GIT_REPO"` recursively removes the directory and its accessible contents. 5. The script recreates the now-empty target and initializes a Git repository, potentially obscuring that unrelated content was deleted. An attacker may exploit this behavior by persuading a user or automated agent to run the converter with a valuable writable directory as the target. ### Impact Assessment The issue can cause permanent deletion of any filesystem content writable by the invoking user under the selected target path. If the script is run by a privileged account, the deletion scope expands to direc ...[truncated 190 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Refuse to operate on an existing or non-empty target directory by default. 2. Require an explicit `--force` option and interactive confirmation before destructive removal. 3. Resolve the source and target to canonical absolute paths before validation. 4. Reject empty paths, `/`, `$HOME`, the current working directory, the source repository, and any target that is an ancestor of the source. 5. Reject symbolic-link targets and check path components for unexpected links before deletion. 6. Prefer creating a new temporary sibling directory and atomically renaming it after successful conversion rather than deleting the destination in advance. 7. Clearly document all destructive behavior and provide a dry-run mode that prints the validated target without modifying it. ]]>
Vulnerability Patterns
  • 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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (13)

Chaining Abuse

High
Category
Tool Misuse
Content
# Try different installation methods
    if command -v apt-get &> /dev/null; then
        sudo apt-get update && sudo apt-get install -y hg-fast-export 2>/dev/null || true
    elif command -v brew &> /dev/null; then
        brew install hg-fast-export 2>/dev/null || true
    fi
Confidence
75% confidence
Finding
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The skill description focuses on conversion benefits but omits that the process creates or modifies a target Git repository path. Users may run it against an unintended directory and lose or overwrite data, especially because repository-conversion tooling often performs many filesystem writes as part of initialization and import.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The documentation states that missing dependencies are auto-installed from GitHub, but it does not clearly warn users that running the skill may fetch and execute third-party code from the network. This creates a supply-chain risk and can surprise users operating in restricted or security-sensitive environments where implicit downloads are not acceptable.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The script silently expands its behavior from local repository conversion to installing external tooling over the network at runtime. This is dangerous because it introduces supply-chain risk, executes unpinned third-party code, and violates least surprise for a conversion utility that users may expect to operate only on local repositories.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The script clones executable conversion tooling from GitHub at runtime and then uses that tool, effectively trusting remote code without verification. If the upstream repository, transport, or local environment is compromised, the script could execute attacker-controlled code on the user's system.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The script unconditionally deletes the target path with rm -rf if it already exists, without confirmation or safety checks beyond variable quoting. A mistaken argument, automation bug, or unexpected path value can destroy user data and make recovery difficult.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The script's stated purpose is repository conversion, but it also performs package installation and fetches code from the network. This expands the trust boundary and can execute unreviewed or tampered external code during a local migration task, which is risky especially in automation or privileged environments.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script installs software and clones code without explicit informed consent, beyond a generic status message. That can surprise users, change system state, and pull in untrusted code paths, which is particularly problematic for a tool expected to perform a deterministic repository conversion.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The network and software-installation behavior is not strictly necessary to convert an existing local repository and is not clearly disclosed as a side effect. This makes the skill more dangerous because users may invoke it expecting offline file conversion but instead trigger package manager actions and a GitHub clone.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
# Try different installation methods
    if command -v apt-get &> /dev/null; then
        sudo apt-get update && sudo apt-get install -y hg-fast-export 2>/dev/null || true
    elif command -v brew &> /dev/null; then
        brew install hg-fast-export 2>/dev/null || true
    fi
Confidence
96% confidence
Finding
Invoking sudo inside a repository conversion helper can elevate a simple content migration task into privileged system modification. If run by a user who can authenticate sudo, the script may install packages and alter the system with root privileges, increasing the blast radius of mistakes or supply-chain compromise.

Missing User Warnings

Low
Confidence
96% confidence
Finding
The script unconditionally truncates or creates the output file using shell redirection before checking whether the target already exists. If a user passes an existing path, especially via the optional output-file argument, important local files could be overwritten or destroyed, causing data loss.

Missing User Warnings

Low
Confidence
83% confidence
Finding
Automatically downloading hg-fast-export without prior user opt-in is a risky side effect for a repository conversion script. While less severe than arbitrary execution by itself, it still creates unanticipated network activity and broadens the trust boundary to external infrastructure.

Missing User Warnings

Low
Confidence
88% confidence
Finding
Writing a cloned dependency into the user's home directory without clear notice creates persistent side effects outside the target repository. While lower impact than privileged installation, it still modifies user state unexpectedly and may leave behind unreviewed executable content on PATH.

Static analysis

No suspicious patterns detected.