Back to skill

Security audit

IMA AI Image Generator & Photo Generator — Poster, Thumbnail, Logo, Art, Illustration, Product & Social Media Graphic Design

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real image generator, but it can expose API keys and image data through under-scoped network and troubleshooting behavior.

Install only if you trust IMA Studio and are comfortable sending prompts, selected local images, and your IMA_API_KEY to its services. Use a scoped or test key first, avoid custom IMA_BASE_URL or IMA_IM_BASE_URL values, do not upload sensitive local files, and do not follow the troubleshooting step that prints the full API key.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/ima_runtime/shared/client.py:16
Finding

Bearer API Credential Can Be Redirected to an Arbitrary Endpoint

Content
View full analysis
int: api_key = args.api_key or os.getenv("IMA_API_KEY") if not api_key: return _fail("API key is required. Use --api-key or set IMA_API_KEY.") # ... if args.list_models: try: tree = get_product_list( args.base_url, api_key, args.task_type, language=args.language, ) except Exception as exc: return _fail(str(exc)) ``` ```python # scripts/ima_runtime/shared/client.py def make_headers(api_key: str, language: str = "en") -> dict: return { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", "x-app-source": "ima_skills", "x_app_language": language, } ``` ```python def get_product_list( base_url: str, api_key: str, category: str, app: str = "ima", platform: str = "web", language: str = "en", ) -> list: response = requests.get( f"{base_url}/open/v1/product/list", params={"app": app, "platform": platform, "category": category}, headers=make_headers(api_key, language), timeout=30, ) ``` ```python response = requests.post( f"{base_url}/open/v1/tasks/create", json=payload, headers=make_headers(api_key), timeout=30, ) ``` ```python response = requests.post( f"{base_url}/open/v1/tasks/detail", json={"task_id": task_id}, headers=make_headers(api_key), ...[truncated 2013 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ima_runtime/shared/inputs.py:33
Finding

Server-Controlled Upload URL Can Exfiltrate Local File Contents

Content
View full analysis
str: if isinstance(source, str) and source.startswith("https://"): logger.info("Using URL directly: %s", source[:50]) return source if not api_key: raise RuntimeError("Local image upload requires IMA API key (--api-key)") if isinstance(source, str): if not os.path.isfile(source): raise RuntimeError(f"Image file not found: {source}") ext = Path(source).suffix.lstrip(".").lower() or "jpeg" with open(source, "rb") as handle: image_bytes = handle.read() content_type = mimetypes.guess_type(source)[0] or "image/jpeg" else: image_bytes = source ext = "jpeg" content_type = "image/jpeg" token_data = get_upload_token(api_key, ext, content_type, im_base_url) ful = token_data.get("ful") fdl = token_data.get("fdl") if not ful or not fdl: raise RuntimeError("Upload token missing 'ful' or 'fdl' field") upload_to_oss(image_bytes, content_type, ful) return fdl ``` ```python # scripts/ima_runtime/shared/client.py def upload_to_oss(image_bytes: bytes, content_type: str, ful: str) -> None: response = requests.put( ful, data=image_bytes, headers={"Content-Type": content_type}, timeout=60, ) response.raise_for_status() ``` ### Technical Analysis The upload-token service controls the `ful` destination used for uploading the complete local file. The runtime does not validate the URL scheme, hostname, port, resolved address, or redirects before send ...[truncated 1684 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/ima_runtime/shared/output_validation.py:105
Finding

Server-Supplied Output URL Enables SSRF and Unbounded Response Download

Content
View full analysis
tuple[int, int]: response = requests.get(url, timeout=timeout) response.raise_for_status() data = response.content for parser in (_parse_png_dims, _parse_jpeg_dims, _parse_webp_dims): dims = parser(data) if dims is not None: return dims raise RuntimeError( "Unable to determine output image dimensions for validation." ) ``` ```python def validate_output_constraints( url: str, raw_params: dict[str, Any], effective_params: dict[str, Any], ) -> None: # ... width, height = fetch_image_dimensions(url) ``` ### Technical Analysis When output size or aspect-ratio constraints require validation, the runtime fetches the media URL returned by the remote task API. That URL is treated as trusted even though no scheme, hostname, resolved address, port, or redirect validation is performed. A malicious or compromised API can return a URL targeting loopback services, private network hosts, link-local metadata services, or other destinations reachable from the Agent host. The request library follows redirects by default, creating an additional route to otherwise blocked destinations unless each redirect is revalidated. The complete response is accessed through ...[truncated 1635 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:4
Finding

Runtime Bootstrap Installs a Broadly Ranged and Unhashed Dependency

Content
View full analysis
=2.25.0 ``` ```python # scripts/ima_runtime/setup.py def _install_requirements() -> None: subprocess.run( [ sys.executable, "-m", "pip", "install", "-r", str(REQUIREMENTS_PATH), ], check=True, ) ``` ### Technical Analysis The documented setup path invokes pip against the active package index. The dependency has only a minimum version and does not specify an exact audited release, upper bound, artifact hash, trusted index, or isolated environment. This is not shell injection because the subprocess uses a fixed argument list. The risk is supply-chain mutability: different installations may resolve different package versions and artifacts. Pip configuration inherited from the environment may also point to an unintended or compromised index. Package installation can execute package build and installation behavior with the privileges of the invoking user. The broad version range means future releases are accepted without review. ### Attack Path 1. A user follows the documented setup process and runs `python3 scripts/ima_runtime_setup.py --install`. 2. The setup script invokes pip using the current environment and configured indexes. 3. Pip resolves any available `requests` version satisfying `>=2.25.0`. 4. A compromised index, altered pip configuration, malicious artifact, or compromised future release is selected. 5. Installation or later import executes code from the unreviewed dependency in the context of the invoking user. ### Impact Assessment If dependency resolution is compromised, attacker-controlled package code can execute with the privileges of the user running se ...[truncated 364 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ima_runtime/shared/config.py:43
Finding

Hardcoded Application Credential and User API Key Included in Query Parameters

Content
View full analysis
tuple[str, str, str]: nonce = uuid.uuid4().hex[:21] ts = str(int(time.time())) raw = f"{APP_ID}|{APP_KEY}|{ts}|{nonce}" sign = hashlib.sha1(raw.encode()).hexdigest().upper() return sign, ts, nonce ``` ```python def get_upload_token( api_key: str, suffix: str, content_type: str, im_base_url: str = DEFAULT_IM_BASE_URL, ) -> dict: sign, ts, nonce = _gen_sign() response = requests.get( f"{im_base_url}/api/rest/oss/getuploadtoken", params={ "appUid": api_key, "appId": APP_ID, "appKey": APP_KEY, "cmimToken": api_key, "sign": sign, "timestamp": ts, "nonce": nonce, "fService": "privite", "fType": "picture", "fSuffix": suffix, "fContentType": content_type, }, timeout=30, ) ``` ### Technical Analysis The application key is embedded directly in distributed source code and participates in the upload-token signature. Any party with access to the Skill package can recover it, so it cannot provide meaningful secrecy as a shared client credential. The user's `IMA_API_KEY` is placed in the URL query twice, as `appUid` and `cmimToken`. Query strings are commonly recorded by reverse proxies, application servers, observability systems, load balancers, browser-like diagnostics, and access logs. TLS protects the URL while in transit but does not prevent endpoint and intermediary logging. Using SHA-1 for the signature also prov ...[truncated 1161 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (41)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This code chunk does not perform any image generation, image transformation, API calls, catalog/runtime interaction, setup, or doctor functionality described in the declaration. Its primary purpose is unrelated support infrastructure for logging. While logging can be a supporting detail in a larger image skill, the evaluation is for whether this supplied code chunk matches the declared description; here, the behavior is materially different. It also accesses the local filesystem to create, rotate, and delete log files, which is not suggested by the declared purpose. Therefore this chunk is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared purpose describes a substantial image-processing/runtime integration capability. The actual code chunk is a minimal init.py containing only the docstring 'CLI presentation helpers.' Based on the provided code alone, its primary purpose is unrelated to image generation or transformation, and none of the declared capabilities are implemented or indicated. This is a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Yes, this is a mismatch. The declared description promises a substantive image-processing/runtime skill, but the provided code chunk is only an empty package initializer with the docstring 'Capability namespace.' It does not demonstrate any of the claimed functionality, resource access, triggers, or runtime behavior. Because the actual code has no meaningful implemented behavior related to the declared purpose, the description does not accurately represent this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

Yes, this is a mismatch for the supplied code chunk. The description claims a substantial image-processing capability built on the IMA Open API and associated runtime behaviors, but the actual file is only an empty package initializer with a docstring. There is no code here that performs any of the declared functions, accesses APIs, handles images, or wires runtime features. Because the evaluation compares the description to this supplied chunk specifically, the description materially overstates what the code actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The description frames the skill as something to use for actual image generation or transformation through the IMA Open API. However, this specific code chunk only implements setup and validation logic: argument parsing, dependency detection, optional pip install -r requirements.txt, diagnostics collection, API-key presence handling, and report output. While this may support the broader image runtime mentioned in the description, the code’s primary purpose is materially different from the declared operational purpose. The setup/doctor aspect is mentioned in the description, but the description still presents the skill as an image-generation/transformation capability; this chunk itself does not execute those capabilities, access image inputs, or call generation endpoints. Therefore this is a meaningful description-versus-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The description presents a broad image runtime with multiple generation/transformation modes and repo-aware operational behavior. This code does not implement runtime behavior; it is only a configuration module. Within that module, the explicitly supported task types are just text_to_image and image_to_image, so the declared capabilities of style transfer and reference-image continuity are not substantiated here. The mention of setup, doctor, and live-catalog-aware runtime is also not represented. Additionally, the code includes hardcoded APP_ID and APP_KEY, which is an access-related detail absent from the description. While configuration files are supporting details, the narrower task support and presence of embedded credentials make the declared purpose materially broader than what this code chunk actually shows.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

There is a clear mismatch between the broad declared purpose and the provided code chunk. The code shown is merely an init.py file with a descriptive docstring about workflow seams for plan confirmation. Based on this chunk alone, it does not implement or evidence the declared image-related capabilities or the stated runtime integrations. Because the actual code behavior presented is materially different and far narrower than the declared purpose, this should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

There is a clear description-behavior mismatch. The declared purpose describes a substantial image-processing skill tied to the IMA Open API and runtime infrastructure. The actual code chunk is a trivial identity function over a workflow plan draft, likely related to confirmation/plan handling rather than image operations. It does not access image resources, call any API, transform data in an image-related way, or implement the described runtime features. Therefore the code's primary purpose is materially different from the declared description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The description promises user-facing image generation/transformation behavior via the IMA Open API. However, this code only exposes a diagnostic 'doctor' command that likely validates runtime/environment configuration. Its primary purpose is operational health checking, not generating or transforming images. While 'doctor' is mentioned in the declared description as part of the setup/runtime, this specific chunk does not implement any of the advertised image capabilities, so the actual behavior is materially different from the declared purpose.

Content

No source excerpt is available for this finding.

YARA rule 'agent_skill_prompt_injection_hidden_instructions': Prompt injection or hidden instructions embedded in AI agent skill text [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · references/shared/catalog-aware-selection.md (reported line 1)May include surrounding context.

md
# Catalog-Aware Dynamic Model Selection

## 1. Purpose

This document defines the formal model-selection contract for image generation requests in this repo.

The goal is to ensure that model choice is driven by:

1. user-specified constraints
2. live catalog capabilities
3. user intent semantics

Model selection must not depend on hardcoded parameter-to-model mappings in documentation or prompt templates.

## 2. Core Principle

The runtime must first determine what the user explicitly requires, then determine what the live catalog can actually support, and only then choose a model.

The live catalog is the capabilit

Instruction Override

High
Category
Prompt Injection
Confidence
90% confidence
Finding

This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Content

Scanner excerpt · references/shared/catalog-aware-selection.md (reported line 101)May include surrounding context.

md
- user preference must not override explicit incompatibility
- recommended defaults must not override explicit incompatibility
- semantic intent only ranks compatible candidates; it does not bypass constraints

## 7. Ranking Among Compatible Models

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/ima_runtime/doctor.py (reported line 63)May include surrounding context.

python
def _run_cli_list_models_smoke(base_url: str, api_key: str, language: str) -> dict:
    entrypoint = Path(__file__).resolve().parents[1] / "ima_runtime_cli.py"
    env = os.environ.copy()
    env["IMA_API_KEY"] = api_key
    result = subprocess.run(
        [

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/ima_runtime/shared/catalog.py (reported line 277)May include surrounding context.

python
for rule in credit_rules:
        attrs = {k.lower().strip(): _normalize_value(v) for k, v in (rule.get("attributes") or {}).items()}
        if all(normalized_user.get(k) == v for k, v in attrs.items()):
            return rule

    return credit_rules[0]

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The keyword block at this location contains extremely broad generic triggers such as 'AI image generator', 'image generator', and related phrases that are common across many ordinary user requests. This can cause the skill to activate in contexts where the user did not specifically intend to use this tool, leading to inappropriate tool routing, unnecessary API use, and possible exposure of user content to external image-generation services.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The Chinese description uses broad natural-language wording like '用中文描述即可生成...' that blurs whether the text is descriptive marketing copy or an invocation trigger. In multilingual environments, ambiguous trigger boundaries increase the chance that normal conversation about posters, product images, or social media graphics will spuriously invoke the skill and send prompts or images to the external service.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill declares powerful capabilities in metadata and instructions: environment secret use (IMA_API_KEY), filesystem write access under ~/.openclaw, network access to external domains, and shell execution via python3 entrypoints, but it does not define an explicit tool/permission scope. That creates an authorization ambiguity where an agent or reviewer cannot clearly constrain what the skill is allowed to do, increasing the chance of overbroad execution and secret exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The playbook instructs operators to run live smoke tests with a real API key and to submit prompts and image inputs to an external API, but it does not explicitly warn that test data will be transmitted to a third-party service. This creates a real risk of accidental disclosure of sensitive prompts, local images, or metadata during testing, especially in operational runbooks that may be followed mechanically.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The troubleshooting steps explicitly instruct users to print the full value of IMA_API_KEY to the terminal, which unnecessarily exposes a sensitive credential on screen and potentially in terminal recordings, scrollback buffers, shared sessions, or support logs. In this skill context, users are likely to follow copy-paste debugging steps, making accidental disclosure of a live API key more likely during troubleshooting.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This markdown file includes recommendation text entirely in Chinese for default model guidance, while the surrounding policy is in English. That creates a language/locale policy concern because the file does not offer user opt-in, translation, or any justification that the skill is intentionally region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The model alias hints include Chinese trigger strings such as "香蕉" and "可梦", which create language-specific behavior in prompt parsing. There is no indication here that users can opt in to this locale-specific matching or choose language behavior, which may violate a language/locale policy requiring neutrality or user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The clarification question and options are hard-coded in Chinese, which imposes a specific language on users without any visible opt-in or fallback. This is a natural-language policy concern because the file contains user-facing text but does not offer locale selection or document a justified region-specific 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/ima_runtime/doctor.py (reported line 65)May include surrounding context.

python
entrypoint = Path(__file__).resolve().parents[1] / "ima_runtime_cli.py"
    env = os.environ.copy()
    env["IMA_API_KEY"] = api_key
    result = subprocess.run(
        [
            sys.executable,
            str(entrypoint),

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/ima_runtime/setup.py (reported line 35)May include surrounding context.

python
def _install_requirements() -> None:
    subprocess.run(
        [sys.executable, "-m", "pip", "install", "-r", str(REQUIREMENTS_PATH)],
        check=True,
    )

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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/ima_runtime/shared/client.py (reported line 163)May include surrounding context.

python
],
    }

    response = requests.post(
        f"{base_url}/open/v1/tasks/create",
        json=payload,
        headers=make_headers(api_key),

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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/ima_runtime/shared/client.py (reported line 190)May include surrounding context.

python
while True:
        if time.time() - start > max_wait:
            raise TimeoutError(f"Task {task_id} timed out after {max_wait}s. Check the IMA dashboard for status.")
        response = requests.post(
            f"{base_url}/open/v1/tasks/detail",
            json={"task_id": task_id},
            headers=make_headers(api_key),

Static analysis

No suspicious patterns detected.