Back to skill

Security audit

Snooker Skill

Security checks for vulnerabilities and agentic risk

Overview

This skill is a straightforward snooker data lookup tool, with the main caution that its optional setup command can save an API key locally in plaintext.

Install only if you are comfortable giving the skill a Snooker API key and allowing it to contact api.snooker.org. Prefer setting SNOOKER_API_KEY instead of running setup; if setup is used, understand that the key is saved locally in plaintext under your home workspace.

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
snooker.py:118
Finding

Plaintext API Key Storage and Command-Line Secret Exposure

Content
View full analysis
None: SNOOKER_DIR.mkdir(parents=True, exist_ok=True) api_key = "" i = 0 while i < len(args): if args[i] == "--api-key" and i + 1 < len(args): api_key = args[i + 1]; i += 2 else: i += 1 if not api_key: api_key = input("X-Requested-By API key: ").strip() CONFIG_FILE.write_text(json.dumps({"apiKey": api_key}, indent=2)) ``` ### Technical Analysis The setup command permits the Snooker API key to be supplied through the `--api-key` command-line argument. Secrets passed this way may be recorded in shell history and can be visible to local process-inspection mechanisms while the command is running. The key is subsequently written in plaintext to `~/.nanobot/workspace/snooker/config.json`. The code does not explicitly set restrictive permissions on either the configuration directory or file. Effective permissions therefore depend on the user's environment and `umask`. In an environment with permissive defaults, another local account or process may be able to read the credential. The interactive fallback uses `input()`, which echoes the API key to the terminal while it is entered. This creates an additional opportunity for visual disclosure or terminal-session logging. The separate behavior of transmitting the key in the `X-Requested-By` header to the fixed HTTPS endpoint `https://api.snooker.org/` is consistent with the documented authentication requirement and does not, by itself, indicate unauthorized exfiltration. ### Attack Path 1. A user invokes the setup command using `snooker.py setup --api-key SECRET`. 2. The secret is retained in shell history or observed through process inspection while the command is running. 3. The script writes ...[truncated 1124 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The core behavior aligns strongly with the declared purpose: it uses api.snooker.org to fetch snooker-related rankings, results, player information, live matches, and head-to-head data. However, the implementation exposes additional user-facing capabilities not reflected in the description, including upcoming match lookup, tournament/schedule views, event-detail lookup, and player/event lookup by numeric ID. It also includes a setup command that persists an API key to ~/.nanobot/workspace/snooker/config.json, which is an undeclared capability relevant to resource access/credential storage. These are not merely invisible implementation details because they are explicit commands and behaviors. Therefore, there is a description-behavior mismatch, though the primary domain/purpose remains snooker data access via api.snooker.org.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill declares executable behavior that can access environment variables and perform network and file operations, but it does not define an explicit tool scope such as permissions or allowed-tools. That creates an overbroad trust boundary: a reviewer or runtime may not have a clear contract for what the skill is allowed to access, increasing the chance of unintended data exposure or misuse if the implementation changes or is abused.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · snooker.py (reported line 26)May include surrounding context.

python
from datetime import date, timedelta
from pathlib import Path

BASE_URL = "https://api.snooker.org/"
WORKSPACE = Path.home() / ".nanobot/workspace"
SNOOKER_DIR = WORKSPACE / "snooker"
CONFIG_FILE = SNOOKER_DIR / "config.json"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The setup command stores the API key in cleartext under the user's home workspace without warning the user about persistent local credential storage or applying any file-permission hardening. If the workspace is shared, backed up, or readable by other local users/processes, the key could be disclosed and abused for unauthorized API access.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The inline comments say the code will try splitting arguments at a -- marker for names like multi-word player names. In reality, the implementation simply splits the argument list in half and never checks for --, so the documentation actively misstates how names are parsed.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The manifest describes rankings, results, player profiles, live matches, and head-to-head records via api.snooker.org. The code additionally implements player-id and event commands, which provide direct numeric-ID lookups for players and events; these are functional capabilities not reflected in the manifest description.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.