Back to skill

Security audit

Skill Sync Publisher

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly transparent about publishing workflows, but it contains high-impact repository publishing behavior with a hard-coded GitHub fork owner and broad implicit invocation.

Review before installing. Use dry-run first, avoid --yes until you have checked the exact platform choices and git diff, and be especially cautious with the Awesome Codex Plugins path because it targets a hard-coded GitHub fork owner rather than clearly using your account. Do not feed untrusted CLI output from this skill back into automated decisions without sanitizing it.

Vulnerability Patterns
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill description presents the workflow as safely validating and synchronizing a local skill across platforms, but the actual behavior includes higher-impact operations such as committing and pushing to GitHub, forking/cloning/editing external repositories, and persisting tracking state under the user's home directory. That mismatch can cause users to authorize the skill under an incomplete understanding of its side effects, increasing the risk of unintended code publication, repository modification, or local state persistence.

Vague Triggers

Medium
Confidence
92% confidence
Finding
Enabling implicit invocation without any trigger constraints allows the skill to be auto-selected in broader contexts than intended, increasing the chance it runs on ambiguous user requests. Because this skill can publish and synchronize content across multiple external registries, unintended invocation could cause unauthorized disclosure, unwanted publication, or accidental updates to third-party platforms.

Unvalidated Output Injection

High
Category
Output Handling
Content
def run(args: list[str], cwd: Path, dry_run: bool = False) -> Result:
    if dry_run:
        return Result("planned", "would run: " + " ".join(args))
    result = subprocess.run(args, cwd=cwd, text=True, capture_output=True, check=False)
    if result.returncode:
        detail = (result.stderr or result.stdout).strip()[-1000:]
        return Result("failed", f"{args[0]} failed: {detail}")
Confidence
80% confidence
Finding
The helper returns raw stderr/stdout text from external tools directly in Result.message after only truncating length. If a downstream agent, UI, or log viewer renders that text with markdown, terminal escape sequences, clickable links, or instruction-following behavior, attacker-controlled repository or CLI output could cause output-injection or prompt-injection style abuse. In this skill context, many commands operate on remote repositories and registries, so external systems can influence returned text and make this more dangerous than a purely local utility.

Unvalidated Output Injection

High
Category
Output Handling
Content
fork = f"{owner}/awesome-codex-plugins"
    view = subprocess.run([gh, "repo", "view", fork], cwd=root, text=True, capture_output=True, check=False)
    if view.returncode:
        created = subprocess.run([gh, "repo", "fork", repo, "--clone=false"], cwd=root, text=True, capture_output=True, check=False)
        if created.returncode:
            return Result("failed", f"could not create Awesome list fork: {(created.stderr or created.stdout).strip()[-1000:]}")
    with tempfile.TemporaryDirectory(prefix="awesome-codex-plugins-") as temp:
Confidence
79% confidence
Finding
On failure, stderr/stdout from gh repo fork is copied directly into a Result message. Remote service responses can contain attacker-influenced repository metadata or crafted text, which may become dangerous if shown in an agent conversation, rich UI, or terminal without escaping. Because this skill automates interactions with external registries and GitHub, relaying remote error text increases the chance of prompt or display-layer injection.

Unvalidated Output Injection

High
Category
Output Handling
Content
["git", "commit", "-m", f"feat: add {info['name']}"],
            ["git", "push", "-u", "origin", branch],
        ):
            result = subprocess.run(command_args, cwd=checkout, text=True, capture_output=True, check=False)
            if result.returncode:
                return Result("failed", f"Awesome list command failed: {(result.stderr or result.stdout).strip()[-1000:]}")
        body = f"Adds [{info['name']}]({source_url}) to the Development & Workflow section.\n\nThe source repository includes the required plugin manifest, security files, and HOL scanner workflow."
Confidence
78% confidence
Finding
Failure output from git commands in the temporary checkout is passed straight through into the Result message. Git error text can include attacker-controlled branch names, repository content, or remote messages, which can be abused for terminal escape injection or prompt manipulation in downstream consumers. The marketplace-publishing context amplifies this because inputs may originate from public repositories and forks.

Unvalidated Output Injection

High
Category
Output Handling
Content
if result.returncode:
                return Result("failed", f"Awesome list command failed: {(result.stderr or result.stdout).strip()[-1000:]}")
        body = f"Adds [{info['name']}]({source_url}) to the Development & Workflow section.\n\nThe source repository includes the required plugin manifest, security files, and HOL scanner workflow."
        pr = subprocess.run([gh, "pr", "create", "--repo", repo, "--head", f"{owner}:{branch}", "--base", "main", "--title", f"feat: add {info['name']}", "--body", body], cwd=checkout, text=True, capture_output=True, check=False)
        if pr.returncode:
            return Result("failed", f"could not open Awesome list PR: {(pr.stderr or pr.stdout).strip()[-1000:]}")
        return Result("published", "Awesome Codex Plugins PR opened", {"remoteUrl": pr.stdout.strip().splitlines()[-1]})
Confidence
80% confidence
Finding
Raw output from gh pr create is returned on failure, and raw stdout is used to derive the final remoteUrl on success. GitHub CLI output can reflect server-side or repository-controlled content, so using it unsafely may enable output injection or cause consumers to trust malformed URLs. In an agent skill that may feed results back into an LLM or UI, this is a meaningful integrity risk.

Static analysis

No suspicious patterns detected.