Back to skill

Security audit

GPT-image-2 图片生成与编辑 诗云API

Security checks for vulnerabilities and agentic risk

Overview

This image skill largely matches its stated purpose, but it needs review because it persists API keys to user environment files by default and downloads API-returned URLs without strong safeguards.

Before installing, users should be comfortable sending prompts and edited images to ShiyunApi. Avoid pasting an API key into the agent unless you are willing for it to be stored persistently in your user environment or shell startup file; prefer setting SHIYUN_API_KEY yourself for the current session. Review downloaded outputs carefully because URLs returned by the service are fetched automatically.

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

Warning
Location
scripts/save_api_key.py:28
Finding

API Key Persisted in Plaintext Shell Startup Files by Default

Content
View full analysis
Path: shell = os.environ.get("SHELL", "") home = Path.home() if shell.endswith("zsh"): target = home / ".zshrc" elif shell.endswith("fish"): target = home / ".config" / "fish" / "config.fish" line = f"set -gx {ENV_NAME} {shell_quote_single(api_key)}" upsert_line(target, f"set -gx {ENV_NAME}", line) return target else: target = home / ".bashrc" line = f"export {ENV_NAME}={shell_quote_single(api_key)}" upsert_line(target, f"export {ENV_NAME}=", line) return target ``` The documented workflow in `SKILL.md:58-59` instructs the Agent to persist a user-provided key through this script: ```markdown 4. 校验 API Key:优先读取 `SHIYUN_API_KEY`。 5. 用户直接提供 API Key 时,运行 `scripts/save_api_key.py --api-key-stdin` 持久化;通过 stdin 传入,不写入文档、日志或 memory。 ``` ### Technical Analysis Although standard input prevents the key from appearing in command-line history, the default `user` scope writes the unencrypted API key into a shell startup file. These files may be included in backups, diagnostic archives, home-directory synchronization, or accidental disclosures. The implementation does not explicitly enforce owner-only permissions. When an existing startup file has permissive permissions, the key inherits that exposure. When a new file is created, its permissions depend on the process umask rather than a security policy. Persistent storage is not required for an individual image-generation or image-editing reques ...[truncated 1077 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_image.py:243
Finding

Unrestricted Retrieval of Response-Controlled URLs

Content
View full analysis
None: request = urllib.request.Request(url, headers={"User-Agent": "WorkBuddy-ShiyunImageSkill/1.0"}) with urllib.request.urlopen(request, timeout=timeout) as response: destination.write_bytes(response.read()) ``` ```python def save_outputs(parsed: Any, output_dir: Path, image_format: str, timeout: int) -> list[Path]: saved: list[Path] = [] items = iter_image_items(parsed) for index, item in enumerate(items, start=1): if not isinstance(item, dict): continue if isinstance(item.get("url"), str): ext = extension_from_url(item["url"], image_format) target = output_dir / f"image_{index}.{ext}" download_url(item["url"], target, timeout) saved.append(target) ``` The image-editing script contains equivalent logic: ```python def download_url(url: str, destination: Path, timeout: int) -> None: request = urllib.request.Request(url, headers={"User-Agent": "WorkBuddy-ShiyunImageEditingSkill/1.0"}) with urllib.request.urlopen(request, timeout=timeout) as response: destination.write_bytes(response.read()) ``` ### Technical Analysis The scripts trust URL fields returned by the remote image API and automatically retrieve them from the Agent host. They do not validate: - The URL scheme - The destination hostname - DNS resolution results - Loopback, private, link-local, reserved, or cloud-metadata addresses - Redirect destinations - Response content type - Downloaded file signature - Maximum response size Consequently, a compromised, malicious, or ...[truncated 2086 chars]
Remediation
View remediation
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • 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 (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

A skill presented as an image-generation/editing tool is reported to persist API credentials into OS/user environment settings, including shell startup files or Windows setx, while not actually performing the advertised image operations. Secret persistence outside the workspace creates long-lived exposure, affects the host beyond the task boundary, and can be abused by other local processes or later sessions.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

A skill presented as an image-generation/editing tool is reported to persist API credentials into OS/user environment settings, including shell startup files or Windows setx, while not actually performing the advertised image operations. Secret persistence outside the workspace creates long-lived exposure, affects the host beyond the task boundary, and can be abused by other local processes or later sessions.

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 214)May include surrounding context.

md
- 不把 API Key 写入 `SKILL.md`、reference、memory 或项目文件。

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares capabilities to read environment variables, read/write files, invoke shell commands, and access the network, but it does not declare any explicit tool scope or allowed-tools restrictions. That omission weakens least-privilege controls and can allow broader execution than reviewers or the runtime expect, especially because the skill handles API keys, local images, and shell-based persistence steps.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger list includes broad everyday phrases such as general image-generation and editing requests, which can cause the skill to auto-invoke in situations where the user did not specifically intend to use ShiyunApi. In this context that is risky because invocation may lead to network uploads of prompts or user images to a third-party provider and could prompt for or use stored API credentials unnecessarily.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The user-facing error guidance strings are hard-coded in Chinese, which imposes a specific language on all users regardless of their locale or preference. The file does not provide any language selection, fallback, or documented region-specific justification for this constraint.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/save_api_key.py (reported line 54)May include surrounding context.

python
def save_windows_user_env(api_key: str) -> None:
    command = ["setx", ENV_NAME, api_key]
    result = subprocess.run(command, capture_output=True, text=True, shell=False)
    if result.returncode != 0:
        message = (result.stderr or result.stdout or "setx failed").strip()
        fail(f"Failed to persist Windows user environment variable: {message}")

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This file presents all instructions, labels, and example outputs exclusively in Chinese, which can amount to a language/locale policy issue when no user opt-in or multilingual alternative is provided. The content does not state that the skill is region-specific or limited to Chinese-speaking users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The error guidance strings are written in Chinese and are always shown for certain API failures, regardless of user locale or preference. This creates a natural-language locale policy issue because the script imposes a specific language without opt-in or justification that it is region-specific.

Content

No source excerpt is available for this finding.