Back to skill

Security audit

fame graphic

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its image-generation purpose, but it has review-worthy handling of API credentials and generated HTML output.

Install only if you are comfortable with prompts being sent to an image API and saved locally. Before use, verify OPENAI_BASE_URL and OPENAI_API_BASE are unset or intentionally trusted, avoid confidential prompts, and be cautious opening or publishing generated index.html files from untrusted prompt 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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/illustrate.py:33
Finding

API Credential and Prompt Disclosure Through an Unvalidated Configurable Endpoint

Content
View full analysis
str: base = ( os.environ.get("OPENAI_BASE_URL") or os.environ.get("OPENAI_API_BASE") or "https://api.openai.com" ).rstrip("/") if base.endswith("/v1"): return f"{base}/images/generations" return f"{base}/v1/images/generations" ``` ```python def _post_json(url: str, api_key: str, payload: dict, timeout_s: int) -> dict: body = json.dumps(payload).encode("utf-8") req = urllib.request.Request( url, data=body, headers={ "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", }, method="POST", ) try: with urllib.request.urlopen(req, timeout=timeout_s) as resp: raw = resp.read() ``` The sensitive request is made at lines 342–358: ```python url = _api_url() items: list[dict] = [] for i, (prompt, metadata) in enumerate(prompts_with_meta, 1): print(f"Generating illustration {i}/{len(prompts_with_meta)}...") payload = { "model": args.model, "prompt": prompt, "size": args.size, "quality": args.quality, "n": 1, "response_format": "b64_json", } data = _post_json(url=url, api_key=api_key, payload=payload, timeout_s=args.timeout) ``` ### Technical Analysis The Skill legitimately needs to send a prompt and API credential to the OpenAI Images API. However, `_api_url()` accepts `OPENAI_BASE_URL` and `OPENAI_API_BASE` directly from the process environment without validating: - The destination hostname - Whether the URL uses HTTPS - Whether the URL contains embedded credentials or an unusual port - Whether the destination is an approved OpenAI or explicitly trusted proxy endpoint The selected U ...[truncated 1948 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/illustrate.py:219
Finding

Stored HTML Injection in the Generated Illustration Gallery

Content
View full analysis
") html.append(f"") html.append("
") if it.get("metadata"): meta = it["metadata"] html.append("

" + meta.get("subject", "Illustration") + "

") tags = [] if meta.get("style"): tags.append(f"style: {meta['style']}") if meta.get("mood"): tags.append(f"mood: {meta['mood']}") if meta.get("type"): tags.append(f"type: {meta['type']}") if meta.get("palette"): tags.append(f"palette: {meta['palette']}") if meta.get("composition"): tags.append(f"comp: {meta['composition']}") if tags: tag_html = " ".join(f'{tag}' for tag in tags) html.append(f'
{tag_html}
') html.append(f"
text
{it['prompt']}
") ``` ### Technical Analysis The generated `index.html` incorporates multiple user-controlled values directly into HTML without context-appropriate encoding. These values include: - Subject - Full custom prompt - Style - Mood - Illustration type - Palette - Composition Although the prompt is placed inside a `
text
` element, that element does not make its contents safe. An input containing closing markup such as `
` can leave the intended context and inject arbitrary HTML or JavaScript. Metadata values can similarly terminate or alter their surrounding elements. The payload is stored in the generated gallery, making this a stored injection issue. Execution occurs when the user or another recipient opens the resulting `index.html`. The risk becomes more significant if the generated directory is published through a web server, attached to a ...[truncated 1440 chars]
Remediation
View remediation
``` 6. Add regression tests using payloads containing `<`, `>`, quotes, closing tags, event handlers, and `
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/illustrate.py (reported line 269)May include surrounding context.

python
p.add_argument("--sleep", type=float, default=0.3, help="Pause between requests (seconds)")
    p.add_argument("--out-dir", default=None)
    p.add_argument("--api-key", default=None)
    p.add_argument("--dry-run", action="store_true", help="Print prompts + exit (no API calls)")
    args = p.parse_args(argv)

    api_key = args.api_key or os.environ.get("OPENAI_API_KEY")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill invokes a script that uses environment variables and network access to call the OpenAI Images API, but the manifest does not declare any tool scope or permissions. This weakens reviewability and containment because consumers cannot clearly see that the skill can access secrets and send data off-host.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill documentation does not warn that user prompts and generated images are transmitted to the OpenAI Images API and that outputs are saved locally. This can lead users to provide sensitive content without understanding the external data flow or the persistence of generated artifacts on disk.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.