Back to skill

Security audit

Release Skills

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed release-helper skill, but its broad install/activation and high-impact git workflow need Review before installation.

Review this skill before installing, especially if you use global skill directories. Prefer installing from a pinned trusted commit or release, run dry-run/preview first, and only allow commit, tag, or push actions after checking the exact repository, branch, files, and version being changed.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T08 · Insecure Dependencies

Warning
Location
README.md:26
Finding
Unpinned Third-Party Package Execution in Installation Instructions## Vulnerability Details **File Location**: `README.md`, line 26 **Vulnerability Type**: Supply-chain risk through unpinned third-party package execution **Risk Level**: Medium **Vulnerable Code**: ```bash npx add https://github.com/wpank/ai/tree/main/skills/tools/release-skills ``` ### Technical Analysis The documented installation command uses `npx` to resolve and execute the npm package named `add`. The command does not pin that package to a reviewed version or verify its integrity. Execution therefore depends on package-registry content that can change after this project has been audited. The Skill source is also referenced through a mutable GitHub branch path. Branch content may change over time, so the installed files are not guaranteed to correspond to the audited revision. The combination of an executable, unpinned npm package and mutable remote source creates an installation-time supply-chain trust boundary that is not protected by version or integrity verification. This issue is in the installation documentation rather than the bundled Python scripts. The reviewed scripts themselves use Python's standard library and do not fetch or execute remote payloads. ### Attack Path 1. An attacker compromises the npm package resolved as `add`, one of its dependencies, or the associated publisher account. Alternatively, an attacker gains control of the mutable upstream branch or its repository. 2. The attacker publishes malicious installation logic or substitutes malicious Skill content. 3. A user follows the documented `npx add ...` command. 4. `npx` downloads and executes the currently resolved package code without validating it against an audited version or expected integrity hash. 5. The malicious package executes with the privileges of the user running the installation command and may install altered Skill files or perform unrelated system actions. ### Impact Assessment Successful exploitation permits arbitrar ...[truncated 520 chars]
Remediation
## Remediation Suggestions 1. Replace the unversioned `npx add` invocation with an installer whose package name and exact version are explicitly pinned. 2. Pin the Skill source to an immutable Git commit or signed release tag instead of a mutable branch path. 3. Publish and verify cryptographic checksums or signatures for downloaded release artifacts. 4. Prefer a non-executing installation method, such as downloading a versioned archive, verifying its checksum, and copying the reviewed files into the destination. 5. If an npm-based installer remains necessary, lock all transitive dependencies, review package lifecycle scripts, and document the expected package publisher and integrity value. 6. In CI environments, run installation with minimal permissions, no unnecessary secrets, and restricted filesystem and network access.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (24)

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
The code is clearly release-preparation related, so the high-level domain matches. However, the description materially overstates capabilities. The script handles version bumping, lightweight validation, changelog generation, and release summaries for skill directories. It uses git only to discover repo root, inspect existing tags, and collect commit messages since a tag. It does not create or apply git tags, does not push to remote, does not publish a release, and does not prepare deployments. The 'multi-language changelogs' claim is unsupported; the changelog is generated in one fixed markdown structure with English section names. 'Auto-detection' and 'universal' are also overstated because execution is manual via CLI flags and targeted specifically at skills under .agents/skills. Therefore this is a description-behavior mismatch due to multiple undeclared/overclaimed primary capabilities.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description promises a broad release automation workflow: detecting changes, bumping versions, updating changelogs, tagging, pushing, and preparing releases. The supplied code does only one narrow part of that story: it reads skill metadata and git logs, then formats aggregated release notes. It does not modify repository state, bump versions, write changelog files, create tags, push to remotes, or implement semantic versioning. While release notes generation is related to release workflows, the primary purpose and capabilities are materially narrower than declared, so this is a clear description-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The code’s real scope is narrow: changelog generation from completed roadmap/TODO items and optional insertion into CHANGELOG.md. That is related to releases, but it does not implement the broader declared workflow features such as semantic versioning, git tagging, pushing, release creation, deployment preparation, or auto-detection. The description materially overstates the skill’s capabilities and primary purpose, so this is a mismatch.

Ae1

High
Category
analysis-evasion
Content
| `scripts/prepare_release.py` | Prepare release with version bump |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| `scripts/release_notes.py` | Generate release notes from commits |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Session Persistence

Medium
Category
Rogue Agent
Content
## When to Use

- User wants to create a release or bump a version
- Updating changelogs before a deploy
- Preparing for deployment with proper tagging
- Triggered by: "release", "new version", "bump version", "update version", "push", "create release", "prepare release", "tag version"
Confidence
75% confidence
Finding
The skill is designed for release operations and explicitly persists as an installable capability that can be triggered by broad phrases including `push` and `release`. In an agent context, that persistence plus ambiguous activation increases the risk of accidental invocation of sensitive actions affecting versioning, changelogs, tags, or deployment preparation across future sessions.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The listed trigger phrases are broad terms like `release`, `push`, and `update version`, which can overlap with normal conversational or development requests. In an agent environment, this increases the chance of unintended activation of a workflow that can modify files, changelogs, tags, or release state.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
The README instructs users to install the skill via `npx add` from a remote GitHub URL without any pinned version, tag, or commit digest. That creates a supply-chain risk: future upstream changes or a compromised repository could cause users to fetch unexpected code or content during installation.

Skill Enumeration

Medium
Category
Agent Snooping
Content
From your project root:

```bash
mkdir -p .claude/skills
cp -r ~/.ai-skills/skills/tools/release-skills .claude/skills/release-skills
```
Confidence
85% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Skill Enumeration

Medium
Category
Agent Snooping
Content
```bash
mkdir -p .claude/skills
cp -r ~/.ai-skills/skills/tools/release-skills .claude/skills/release-skills
```

#### Claude Code (global)
Confidence
85% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Skill Enumeration

Medium
Category
Agent Snooping
Content
#### Claude Code (global)

```bash
mkdir -p ~/.claude/skills
cp -r ~/.ai-skills/skills/tools/release-skills ~/.claude/skills/release-skills
```
Confidence
85% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Skill Enumeration

Medium
Category
Agent Snooping
Content
```bash
mkdir -p ~/.claude/skills
cp -r ~/.ai-skills/skills/tools/release-skills ~/.claude/skills/release-skills
```

---
Confidence
85% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill describes shell execution, file reads/writes, and environment access but does not declare any explicit tool scope or permissions boundaries. In a release workflow, these capabilities can modify repository state, create commits/tags, and push to remotes, so missing scope declarations increases the risk of over-privileged or unintended execution.

External Model or Provider Selection

Medium
Category
Excessive Agency
Content
---
name: release-skills
model: fast
description: |
  WHAT: Universal release workflow with auto-detection, multi-language changelogs, semantic versioning, and git tagging.
Confidence
90% confidence
Finding
Skill selects an external model or provider that may use a different account or billing plan than the operator expects. Undisclosed model switches can cause unexpected cost or quota consumption.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The trigger keywords include broad terms like "release," "push," and "new version," which can cause unintended invocation in ordinary conversations. Because this skill includes repository-modifying and push-related steps, accidental activation could lead to inappropriate suggestions or execution attempts in a sensitive development context.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## NEVER

- Force push to main/master
- Skip user confirmation before push
- Create tags without commits
- Include internal/chore changes in user-facing changelog
- Push without explicit user consent
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
patterns = [f"{skill_name}/v*", f"{skill_name}-v*", "v*"]
    for pattern in patterns:
        try:
            out = subprocess.check_output(
                ["git", "tag", "-l", pattern, "--sort=-v:refname"],
                stderr=subprocess.DEVNULL, text=True
            ).strip()
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def git_root() -> Path:
    """Find the repository root."""
    try:
        out = subprocess.check_output(
            ["git", "rev-parse", "--show-toplevel"],
            stderr=subprocess.DEVNULL, text=True
        ).strip()
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def git_root() -> Path:
    """Find the repository root."""
    try:
        out = subprocess.check_output(
            ["git", "rev-parse", "--show-toplevel"],
            stderr=subprocess.DEVNULL, text=True
        ).strip()
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if path:
        cmd.extend(["--", path])
    try:
        out = subprocess.check_output(cmd, stderr=subprocess.DEVNULL, text=True).strip()
    except (subprocess.CalledProcessError, FileNotFoundError):
        return []
    if not out:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if path:
        cmd.extend(["--", path])
    try:
        out = subprocess.check_output(cmd, stderr=subprocess.DEVNULL, text=True).strip()
    except (subprocess.CalledProcessError, FileNotFoundError):
        return []
    if not out:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def file_added_after(filepath: Path, since: str) -> bool:
    """Check if a file was first added to git after the given date."""
    try:
        out = subprocess.check_output(
            ["git", "log", "--diff-filter=A", "--format=%aI",
             "--follow", "--", str(filepath)],
            stderr=subprocess.DEVNULL, text=True
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Tainted flow: 'updated' from pathlib.Path.read_text (line 329, file read) → pathlib.Path.write_text (file write)

Medium
Category
Data Flow
Content
else:
        updated = content.rstrip("\n") + "\n\n" + new_section

    changelog_path.write_text(updated)


# ---------------------------------------------------------------------------
Confidence
65% confidence
Finding
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Missing User Warnings

Low
Confidence
83% confidence
Finding
This code performs a write to the changelog file via write_text(), creating or modifying CHANGELOG.md when --append is used. Although the CLI help mentions append behavior, the write path itself has no confirmation prompt and no inline comment/docstring warning near the destructive file-modification operation.

Static analysis

No suspicious patterns detected.