Back to skill

Security audit

Showmeai

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its media-generation purpose, but it has credential-handling weaknesses that could leak a ShowMeAI API key to unintended hosts.

Review before installing. This skill needs a ShowMeAI API key and will send prompts and selected local media to the configured ShowMeAI endpoint. Do not use it with sensitive media unless you are comfortable sharing it with the service, avoid custom API base URLs, and rotate the key if you suspect it may have been exposed through result downloads or endpoint misconfiguration.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/showmeai_core/outputs.py:85
Finding

Bearer Credential Forwarded to Arbitrary Result URLs

Content
View full analysis
Path: parsed = urllib.parse.urlparse(url) if parsed.scheme not in {"http", "https"}: raise SkillError("OUTPUT_URL_INVALID", "Only HTTP(S) result URLs are accepted.") suffix = Path(parsed.path).suffix.lstrip(".") if not suffix: suffix = mimetypes.guess_extension("application/octet-stream", strict=False).lstrip(".") or "bin" raw, _headers = client.request("GET", url, timeout=300) return self.write_bytes(raw, stem, suffix, filename) ``` ```python # scripts/showmeai_core/http.py:74-90 def request( self, method: str, url: str, *, body: bytes | None = None, content_type: str = "application/json", timeout: int = 300, ) -> tuple[bytes, dict[str, str]]: headers = {"Authorization": f"Bearer {self.api_key}"} if body is not None: headers["Content-Type"] = content_type last_error: Exception | None = None for attempt in range(self.retries + 1): request = urllib.request.Request(url, method=method, headers=headers, data=body) try: with urllib.request.urlopen(request, timeout=timeout) as response: return response.read(), dict(response.headers.items()) ``` ### Technical Analysis `OutputManager.download()` accepts every syntactically valid HTTP or HTTPS URL. It does not verify that the destination belongs to the configured ShowMeAI API origin or to an explicitly trusted media host. The accepted URL is passed to `ApiClient.request()`, which unconditionally adds the ShowMeAI API key as a bearer credential. Consequently, ...[truncated 1948 chars]
Remediation
View remediation
tuple[bytes, dict[str, str]]: request = urllib.request.Request(url, method="GET") with urllib.request.urlopen(request, timeout=timeout) as response: return response.read(), dict(response.headers.items()) ``` 2. Do not attach the API bearer credential to arbitrary result URLs. Use authenticated downloads only when the normalized destination origin exactly matches the validated API origin. 3. Compare origins using parsed scheme, hostname, and effective port rather than string-prefix matching. 4. Maintain an explicit allowlist if ShowMeAI requires authenticated downloads from documented CDN or object-storage hosts. 5. Disable automatic redirects for credentialed requests or implement redirect handling that strips `Authorization` whenever the destination origin changes. 6. Reject plaintext HTTP result URLs unless there is a documented and explicitly enabled compatibility requirement. 7. Add tests proving that: - Cross-origin result downloads contain no `Authorization` header. - Same-origin authenticated API calls retain the header. - Cross-origin redirects strip the header. - Unsupported URL schemes and embedded URL credentials are rejected. 8. Rotate any API keys that may already have been exposed through cross-origin result downloads. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/showmeai.py:61
Finding

Unvalidated API Base URL Can Redirect Credentials and User Media

Content
View full analysis
ApiClient: api_key = key or resolve_api_key()[0] base_url = str(config.get("api", {}).get("base_url", DEFAULT_BASE_URL)).rstrip("/") if not base_url: base_url = DEFAULT_BASE_URL return ApiClient(base_url, api_key) ``` ```python # scripts/showmeai.py:203-223 def command_setup(args: argparse.Namespace) -> dict[str, Any]: config = load_config() base_url = (args.base_url or config["api"].get("base_url") or DEFAULT_BASE_URL).rstrip("/") existing_key, existing_source = resolve_api_key(required=False) if args.key_stdin: api_key = sys.stdin.readline().strip() if not api_key: raise SkillError("KEY_MISSING", "No API key was received on stdin.") key_is_new = True elif existing_key and not args.replace_key: api_key = existing_key key_is_new = False else: api_key = getpass.getpass("ShowMeAI API key (input hidden): ").strip() key_is_new = True if len(api_key) < 8: raise SkillError("KEY_INVALID", "API key is too short.") client = ApiClient(base_url, api_key) live_payload = client.models() ``` ```python # scripts/showmeai.py:397-407 def command_config_set(args: argparse.Namespace) -> dict[str, Any]: config = load_config() value = _parse_value(args.value) cataloged = not (args.path.endswith(".model") and isinstance(value, str)) or model_definition(value) is not None set_path(config, args.path, value) parts = args.path.split(".") if len(parts) >= 3 and parts[0] == "defaults" and parts[1] in ONBOARDING_CATEGORIES: reset_onboardin ...[truncated 2551 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

There is a clear description-to-code mismatch. The declared description promises substantial media-processing and runtime capabilities, but the provided code chunk is only package metadata in init.py. It neither implements nor exposes the listed behaviors in this snippet. Because the actual code’s observable behavior is limited to version declaration, the declared primary purpose is not represented by the supplied code chunk.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 76)May include surrounding context.

md
ey-stdin` must never silently complete model onboarding. See [configuration.md](references/configuration.md).

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 82)May include surrounding context.

md
ey-stdin` must never silently complete model onboarding. See [configuration.md](references/configuration.md).

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 117)May include surrounding context.

md
ey-stdin` must never silently complete model onboarding. See [configuration.md](references/configuration.md).

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 115)May include surrounding context.

md
See [README.md](README.md) for the annotated distribution tree covering entry points, shared modules, data, on-demand references, and tests.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 117)May include surrounding context.

md
See [README.md](README.md) for the annotated distribution tree covering entry points, shared modules, data, on-demand references, and tests.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 121)May include surrounding context.

md
See [README.md](README.md) for the annotated distribution tree covering entry points, shared modules, data, on-demand references, and tests.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 117)May include surrounding context.

md
Distribution inventory: `SKILL.md`, `README.md`, `README.zh-CN.md`, `DESIGN.md`, `CHANGELOG.md`, `LICENSE`, `data/model-catalog.json`, `references/audio.md`, `r

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 117)May include surrounding context.

md
Distribution inventory: `SKILL.md`, `README.md`, `README.zh-CN.md`, `DESIGN.md`, `CHANGELOG.md`, `LICENSE`, `data/model-catalog.json`, `references/audio.md`, `r

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 117)May include surrounding context.

md
hree-d.md`, `references/video.md`, `scripts/gen.py`, `scripts/image_to_3d.py`, `scripts/showmeai.py`, `scripts/video_gen.py`, `scripts/showmeai_core/__init__.py

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill explicitly invokes a Python runtime that can read/write files, access environment-backed secrets, make network requests, and execute shell commands, but it declares no tool scope or permission boundaries in the manifest. That creates an avoidable trust gap: a host agent may enable the skill without clear least-privilege constraints, increasing the chance of unintended filesystem access, secret handling, or command execution beyond what the user expects.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% 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.

Content

Scanner excerpt · references/configuration.md (reported line 29)May include surrounding context.

python3 scripts/showmeai.py onboarding apply --category image --model gemini-3.1-flash-image --params-json '{"n":1,"image_size":"1K","aspect_ratio":"1:1"}' --json

text

The model list places the recommendation first and includes each model's supported parameter schema. Ask for an explicit choice, validate only supported values, and save it with `onboarding apply`. Once complete, use the saved default without asking again unless the user requests an override.

Onboarding is progressive: an image request only requires image defaults. A later first video request configures video without asking for the Key again. Existing version-2 configurations migrate to `needs_defaults` once so their inherited defaults can be reviewed.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% 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.

Content

Scanner excerpt · references/configuration.md (reported line 31)May include surrounding context.

python3 scripts/showmeai.py onboarding apply --category image --model gemini-3.1-flash-image --params-json '{"n":1,"image_size":"1K","aspect_ratio":"1:1"}' --json

text

The model list places the recommendation first and includes each model's supported parameter schema. Ask for an explicit choice, validate only supported values, and save it with `onboarding apply`. Once complete, use the saved default without asking again unless the user requests an override.

Onboarding is progressive: an image request only requires image defaults. A later first video request configures video without asking for the Key again. Existing version-2 configurations migrate to `needs_defaults` once so their inherited defaults can be reviewed.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% 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.

Content

Scanner excerpt · scripts/showmeai.py (reported line 376)May include surrounding context.

python
python3 scripts/showmeai.py onboarding apply --category image --model gemini-3.1-flash-image --params-json '{"n":1,"image_size":"1K","aspect_ratio":"1:1"}' --json
```

The model list places the recommendation first and includes each model's supported parameter schema. Ask for an explicit choice, validate only supported values, and save it with `onboarding apply`. Once complete, use the saved default without asking again unless the user requests an override.

Onboarding is progressive: an image request only requires image defaults. A later first video request configures video without asking for the Key again. Existing version-2 configurations migrate to `needs_defaults` once so their inherited defaults can be reviewed.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documentation explicitly states that local input files are transmitted to upstream services, but it does not warn users that those images may contain sensitive personal, proprietary, or regulated data. In a media-generation skill, users are likely to provide photos and reference images, so omission of a privacy warning can lead to unintentional disclosure to third-party processors.

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 · scripts/showmeai_core/config.py (reported line 18)May include surrounding context.

python
from .paths import config_file, credentials_file


DEFAULT_BASE_URL = "https://api.showmeai.art/v1"
ONBOARDING_CATEGORIES = ("image", "video", "3d", "tts", "music")

DEFAULT_CONFIG: dict[str, Any] = {

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

Line L29 says the Agent contract was standardized on English execution instructions. This indicates a language constraint in natural-language policy without any sign here of user choice, opt-in, or a documented region-specific justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The line presents the documentation with English as the default and Chinese as an alternate link, which can indicate a language preference baked into the skill's user-facing materials. Because no explicit language choice or broader locale option is offered in this file, this may conflict with a policy requiring language choice or opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The code reads an API key from a credentials file and can persist a new API key to disk, which is a safety-relevant credential-handling operation. While the module and function names imply configuration behavior, there is no confirmation prompt, user-facing log/print, or inline warning/comment disclosing that credentials are being read from and written to local storage.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.