Back to skill

Security audit

Package Version Tracker

Security checks for vulnerabilities and agentic risk

Overview

This skill coherently queries public npm and PyPI package version data, with limited and disclosed network use and no evidence of hidden persistence, credential access, or destructive behavior.

Before installing, consider narrowing the activation triggers if you do not want ordinary package-version discussions to make registry requests. Treat displayed package descriptions, authors, and summaries as untrusted registry content.

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
scripts/package_version_tracker.py:130
Finding
Untrusted Registry Metadata Is Rendered Without Sanitization<![CDATA[ ## Vulnerability Details **File Location**: `scripts/package_version_tracker.py`, lines 16-27, 61-75, and 130-143 **Vulnerability Type**: Unsanitized rendering of attacker-controlled remote content **Risk Level**: Medium ### Vulnerable Code ```python with urllib.request.urlopen(url, timeout=10) as response: data = json.loads(response.read().decode()) return { "success": True, "name": data.get("name"), "version": data.get("version"), "description": data.get("description", ""), "license": data.get("license", ""), "homepage": data.get("homepage", ""), "repository": data.get("repository", {}).get("url", ""), } ``` ```python with urllib.request.urlopen(url, timeout=10) as response: data = json.loads(response.read().decode()) info = data.get("info", {}) return { "success": True, "name": info.get("name"), "version": info.get("version"), "summary": info.get("summary", ""), "author": info.get("author", ""), "license": info.get("license", ""), "home_page": info.get("home_page", ""), "pypi_url": info.get("package_url", ""), } ``` ```python lines = [] lines.append(f"📦 **{package_type.upper()} Package: {data.get('name', 'N/A')}**") lines.append(f"") lines.append(f"**Version:** `{data.get('version', 'N/A')}`") if package_type == "npm": if data.get("description"): lines.append(f"**Description:** {data.get('description')}") if data.get("license"): lines.append(f"**License:** {data.get('license')}") else: # pypi if data.get("summary"): lines.append(f"**Summary:** {data.get('summary')}") if data.get("author"): lines.append(f"**Author:** {data.get('author')}") ``` ### Technical Analysis The skill retrieves package metadata from public npm and PyPI registry APIs. Fields including the package name, version, description, license, summary, and author are controlled by pac ...[truncated 2703 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat all registry response fields as untrusted external data. 2. Remove ANSI escape sequences and disallowed C0/C1 control characters before rendering values. 3. Escape Markdown metacharacters when generating Markdown output, or emit a structured format such as JSON when the output will be consumed programmatically. 4. Place remote text in clearly delimited quoted or code blocks and label it as registry-supplied metadata. 5. Apply reasonable length limits to fields such as descriptions, summaries, authors, package names, and licenses. 6. Keep data and instructions separated in downstream AI workflows. Tool responses should explicitly state that registry metadata must never be followed as instructions. 7. Consider a centralized sanitization function, for example: ```python import re ANSI_ESCAPE = re.compile(r"\x1b(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])") CONTROL_CHARS = re.compile(r"[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]") def sanitize_registry_text(value: object, max_length: int = 2000) -> str: text = "" if value is None else str(value) text = ANSI_ESCAPE.sub("", text) text = CONTROL_CHARS.sub("", text) return text[:max_length] ``` 8. Apply the sanitizer immediately after parsing the registry response and perform context-specific Markdown escaping at the final rendering sink. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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 (4)

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The skill documentation is entirely presented in Chinese, including the feature descriptions and usage guidance, with no indication that users may choose another language or that the skill is intentionally limited to a Chinese-speaking context. This can constitute a language/locale policy issue because it implicitly constrains interaction language without opt-in.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The trigger phrases include very broad terms like "package version", "pypi 版本", and especially "pip show", which can match ordinary user requests without clearly constraining invocation to this specific skill. Overbroad triggers increase the chance of unintended activation, misrouting user requests, and causing the agent to perform network lookups when the user did not explicitly intend to use this capability.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The trigger set includes multiple ambiguous phrases such as general package/version references and terms like 'pip show', which may appear in normal technical discussions without the user intending to run this skill. In this context, ambiguous activation increases the chance of unsolicited network access and unintended skill execution during routine developer conversations.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The trigger phrase at line 26 is broad enough to match ordinary conversation about package versions rather than an intentional skill invocation. Because this skill has network permission, accidental activation could cause unintended external requests and expose user queries or context to remote package registries.

Static analysis

No suspicious patterns detected.