Back to skill

Security audit

ZM IMG2 视觉提示词编排

Security checks for vulnerabilities and agentic risk

Overview

The skill is a mostly legitimate image-prompt workflow, but it needs review because its code can hand local image paths to an external provider through an undeclared generation dependency.

Review before installing. Use dry-run by default, do not run this on untrusted JSON/YAML specs, and do not provide reference image paths unless you are comfortable with those images and prompts being used by the configured external image provider. The publisher should align the declared and executed dependency and restrict reference images to approved asset directories before broad use.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/compile_and_run.py:56
Finding

Unrestricted local reference paths may expose files to an external image-generation workflow

Content
View full analysis
str: p = pathlib.Path(os.path.expanduser(path)) if not p.is_absolute(): p = WORKSPACE / p return str(p.resolve()) def choose_reference_images(data: Dict[str, Any], args: argparse.Namespace) -> List[str]: refs = [] if args.reference_image: refs.extend(args.reference_image) else: refs.extend(as_list(data.get("reference_images"))) if args.style_image: refs.append(args.style_image) forbidden_terms = [x.lower() for x in as_list(data.get("forbidden")) + as_list(args.forbidden)] forbidden_image_terms = [x for x in forbidden_terms if x] out = [] seen = set() for ref in refs: full = resolve_path(ref) name_low = pathlib.Path(full).name.lower() stem_low = pathlib.Path(full).stem.lower() if any(term in name_low or term == stem_low for term in forbidden_image_terms): raise SystemExit(f"forbidden input image rejected: {ref}") if full not in seen: out.append(full) seen.add(full) if args.require_character_refs and not out: raise SystemExit("input_images must not be empty when --require-character-refs is set") if len(out) > args.max_input_images: raise SystemExit(f"too many input_images: {len(out)} > {args.max_input_images}") missing = [p for p in out if not pathlib.Path(p).exists()] if missing: raise SystemExit("missing input image(s): " + ", ".join(missing)) return out ``` The selected files are subsequently passed to the external image-generation workflow: ```python cmd = [sys.executable, str(DIRECT_RUN), "--prompt", prompt, "--task-name", task_name, "--provider", args.provider, "--model", ...[truncated 2955 chars]
Remediation
View remediation
pathlib.Path: candidate = pathlib.Path(value).expanduser() if not candidate.is_absolute(): candidate = WORKSPACE / candidate candidate = candidate.resolve(strict=True) try: candidate.relative_to(TRUSTED_REFERENCE_ROOT) except ValueError: raise SystemExit("reference image is outside the trusted asset directory") if not candidate.is_file(): raise SystemExit("reference image must be a regular file") return candidate ``` 2. Reject absolute paths and traversal syntax at the input boundary unless there is a documented need for them. 3. Resolve symlinks before applying the trusted-root check, as shown above. 4. Validate file type using content-based image decoding rather than filename extensions alone. 5. Add a separate explicit option or confirmation gate for transmitting local files to an external provider. 6. Record the provider destination and approved reference paths before execution without copying sensitive file contents into logs. 7. Treat specifications from chats, repositories, or remote task systems as untrusted input. 8. Add automated tests covering absolute paths, `..` traversal, home expansion, symlink escape, directories presented as files, and malformed image content. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/compile_and_run.py:13
Finding

Runtime dependency does not match the dependency declared in skill metadata and documentation

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (12)

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/compile_and_run.py (reported line 146)May include surrounding context.

python
if visible_forbidden:
        parts.append("Forbidden: " + ", ".join(dict.fromkeys(visible_forbidden)) + ".")
    prompt = "\n".join(x.strip() for x in parts if x and x.strip())
    return prompt


def write_json(path: pathlib.Path, data: Dict[str, Any]) -> None:

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares executable behavior and filesystem interaction via Python scripts, artifact creation, and shell commands, but it does not define any explicit tool scope such as permissions or allowed-tools. That makes the runtime authority implicit rather than constrained, increasing the chance an agent can invoke broader shell or file capabilities than a user expects.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly states that reference images are routed to an external Happy OpenAI-compatible provider, but the documentation does not clearly foreground that user-supplied images and prompts leave the local environment. Because the referenced use cases include comic pages, covers, and character images, the transmitted data may contain sensitive, proprietary, or personal content, creating privacy and data-governance risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The default style string and compiled prompt explicitly require Chinese output via phrases like 'minimal Chinese text', 'Square Chinese science comic', and 'minimal big readable Chinese'. This enforces a specific language/locale in natural-language instructions without offering the user a choice or documenting a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest describes this skill as compiling structured visual requirements into prompts and checking references, style, forbidden items, and IMG2 evidence. In addition to that expected compilation/review role, the code supports --run and executes happy-img2-direct via subprocess.run, which moves the skill from prompt orchestration into actually triggering image generation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

For a skill described as compiling visual requirements into prompts and checking inputs/evidence, spawning another script as a subprocess is not an obvious or necessary capability. This gives the skill operational execution behavior beyond mere prompt transformation and validation.

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/compile_and_run.py (reported line 227)May include surrounding context.

python
if should_run:
        started = time.time()
        proc = subprocess.run(cmd, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=args.timeout_ms / 1000 + 45)
        elapsed = round(time.time() - started, 3)
        (run_dir / "stdout.txt").write_text(proc.stdout or "", encoding="utf-8")
        (run_dir / "stderr.txt").write_text(proc.stderr or "", encoding="utf-8")

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The entire execution prompt is written as mandatory Chinese-language instructions, including required outputs and operational constraints, with no indication that the user or subagent may choose another language. This creates a natural-language policy concern because it imposes a specific language by default rather than documenting a justified locale restriction or offering opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
72% confidence
Finding

The text says the compiler produces prompts of about 200-500 Chinese/English characters, which suggests a fixed language scope. Because no user opt-in or locale-selection behavior is described, this can be read as a language policy constraint that is not clearly justified in the file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The checklist is written entirely in Chinese, and there is no indication that users may choose another language or that the skill is intentionally limited to a Chinese-speaking or region-specific context. This can constitute a language/locale policy issue under the natural-language policy category.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The style instruction explicitly requires 'minimal Chinese text', which is a natural-language locale constraint embedded in the file. There is no indication that the user can choose another language or that the skill is intentionally limited to a Chinese-only regional use case.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

This markdown file presents all user-facing instructions exclusively in Chinese, and there is no indication that the user can choose another language or that the Chinese-only constraint is justified. Under the policy rule for natural-language violations, forcing a specific language without user opt-in is in scope.

Content

No source excerpt is available for this finding.