Back to skill

Security audit

Creative Brief转广告全案|AI-HIVE

Security checks for vulnerabilities and agentic risk

Overview

This skill appears purpose-related rather than malicious, but it needs review because its helper scripts handle API credentials and local downloads without enough endpoint and path validation.

Install only if you trust the AI-HIVE endpoint and are comfortable storing an API key locally. Use the default HTTPS AI-HIVE base URL, avoid alternate base URLs unless using a separate test key, choose a contained output directory, review parameters before any billable generation, and watch for unexpected large downloads or overwritten files.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/imagegen.py:397
Finding

API-Controlled Path Traversal Allows Filesystem Writes Outside the Output Directory

Content
View full analysis

Vulnerability Details

File Location: scripts/imagegen.py:397-414; duplicated in scripts/videogen.py:397-414
Vulnerability Type: Path traversal and arbitrary file overwrite
Risk Level: Medium

Vulnerable Code

python
out_dir = Path(output_dir)
out_dir.mkdir(parents=True, exist_ok=True)
task_type = task.get("taskType", "task")
for i, item in enumerate(succeeded):
    result_url = item.get("resultUrl")
    if not result_url:
        continue
    ext = ".mp4" if "video" in task_type.lower() else ".png"
    filename = f"{task_type}_{task_id}_{i+1}{ext}"
    out_path = out_dir / filename
    download_file(result_url, out_path)

# Tail frame
for item in succeeded:
    last_frame = item.get("lastFrameUrl")
    if last_frame:
        out_path = out_dir / f"{task_type}_{task_id}_lastframe.png"
        download_file(last_frame, out_path)

The destination is subsequently opened in write-and-truncate mode:

python
with open(str(out_path), "wb") as f:
    for chunk in resp.iter_content(chunk_size=8192):
        if chunk:
            f.write(chunk)

Technical Analysis

The API response controls taskType, while taskId can originate from an API generation response or command input. These values are interpolated directly into a filename without removing path separators, resolving the destination, or verifying that the resolved path remains under output_dir.

pathlib does not neutralize traversal components when joining paths. For example, a taskType containing ../../destination produces a path such as:

text
/configured/output/../../destination_task-id_1.png

The download routine then opens the path with "wb", which creates a missing file or truncates an existing file. The same vulnerable implementation exists in both generation clients.

Attack Path

  1. A user invokes image or video generation and the client polls the configured API. 2 ...[truncated 1109 chars]
Remediation
View remediation

Remediation Suggestions

  • Do not use API-controlled values as local filenames. Generate filenames locally using a UUID or validated numeric index.

  • If identifiers must be retained, restrict them to a conservative allowlist such as [A-Za-z0-9_-].

  • Resolve and validate every destination before opening it:

    python
    import re
    from pathlib import Path
    
    safe_task_type = re.sub(r"[^A-Za-z0-9_-]", "_", str(task_type))
    safe_task_id = re.sub(r"[^A-Za-z0-9_-]", "_", str(task_id))
    
    root = Path(output_dir).expanduser().resolve()
    root.mkdir(parents=True, exist_ok=True)
    destination = (root / f"{safe_task_type}_{safe_task_id}_{i + 1}{ext}").resolve()
    
    if not destination.is_relative_to(root):
        raise SystemExit("Refusing to write outside the output directory")
    
  • Download into a temporary file inside the validated directory and atomically rename it after validation.

  • Avoid silent truncation. Use exclusive creation or require explicit permission before replacing an existing file.

  • Apply the same correction to scripts/videogen.py.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/imagegen.py:91
Finding

Bearer API Key Can Be Sent to an Untrusted or Plaintext Base URL

Content
View full analysis

Vulnerability Details

File Location: scripts/imagegen.py:91-99, 130-143; duplicated in scripts/videogen.py:91-99, 130-143
Vulnerability Type: Insufficient endpoint validation leading to credential disclosure
Risk Level: Medium

Vulnerable Code

python
def _resolve_base_url(self, cli_url):
    if cli_url:
        return cli_url.rstrip("/")
    env_url = os.environ.get("AI_HIVE_BASE_URL")
    if env_url:
        return env_url.rstrip("/")
    file_config = self._read_config_file()
    if file_config.get("base_url"):
        return file_config["base_url"].rstrip("/")
    return DEFAULT_BASE_URL

The unrestricted URL is used with the bearer credential:

python
class AiHiveClient:
    def __init__(self, config):
        self.config = config
        self.base = config.base_url
        self.headers = {
            "Authorization": f"Bearer {config.api_key}",
            "Content-Type": "application/json",
        }

    def _url(self, path):
        return f"{self.base}/openapi/v1/{path}"

    def _request(self, method, url, **kwargs):
        self.config.log(f"{method} {url}")
        try:
            resp = requests.request(
                method, url, headers=self.headers,
                timeout=DEFAULT_TIMEOUT, **kwargs
            )

Technical Analysis

The Base URL can be supplied through a command-line argument, environment variable, or persistent configuration file. The value is accepted without validating its scheme, hostname, port, or relationship to the intended AI-HIVE service.

Every API request includes the Authorization: Bearer header. Consequently, selecting an attacker-controlled endpoint causes the AI-HIVE key to be transmitted to that endpoint. A plaintext http:// URL additionally exposes the credential to network interception.

This behavior is broader than the minimum privileges required for the declared Skill, which normal ...[truncated 988 chars]

Remediation
View remediation

Remediation Suggestions

  • Require HTTPS for all authenticated endpoints.
  • Allowlist the documented production hostname by default.
  • Reject URLs containing embedded credentials, unexpected ports, fragments, or non-HTTP schemes.
  • Make alternate endpoints available only through an explicit development option that displays a warning and does not automatically reuse the production credential.
  • Use separate credentials for development endpoints.
  • Revalidate the final response hostname after redirects, or disable cross-origin redirects for authenticated requests.
  • Apply the same validation to both generation scripts.

Example validation:

python
from urllib.parse import urlparse

parsed = urlparse(candidate)
if parsed.scheme != "https":
    raise SystemExit("The API Base URL must use HTTPS")
if parsed.hostname != "ai-hive.iclip.cn":
    raise SystemExit("Untrusted API hostname")

T09 · Insecure Skill Coding Practices

Note
Location
scripts/imagegen.py:312
Finding

Unrestricted API-Directed Downloads Can Exhaust Disk Space and Reach Untrusted Endpoints

Content
View full analysis

Vulnerability Details

File Location: scripts/imagegen.py:312-332; duplicated in scripts/videogen.py:312-332
Vulnerability Type: Unbounded download and insufficient URL validation
Risk Level: Low

Vulnerable Code

python
def download_file(url, out_path, timeout=300):
    """Stream a file download while displaying progress."""
    print(f"[download] {out_path.name}")
    try:
        resp = requests.get(url, stream=True, timeout=timeout)
        resp.raise_for_status()
        total = int(resp.headers.get("content-length", 0))
        downloaded = 0
        with open(str(out_path), "wb") as f:
            for chunk in resp.iter_content(chunk_size=8192):
                if chunk:
                    f.write(chunk)
                    downloaded += len(chunk)
                    if total > 0:
                        pct = int(downloaded * 100 / total)
                        bar = "█" * (pct // 5) + "░" * (20 - pct // 5)
                        print(
                            f"\r  {bar} {pct}% "
                            f"({downloaded // 1024}KB)",
                            end="",
                            flush=True,
                        )
        print()
        size_mb = downloaded / (1024 * 1024)
        print(f"[ok] {out_path} ({size_mb:.1f} MB)")
    except requests.exceptions.RequestException as e:
        print(f"\n[error] Download failed: {e}", file=sys.stderr)

Technical Analysis

The task API supplies resultUrl and lastFrameUrl, which are passed directly to requests.get(). The client does not validate the URL scheme or destination host and follows the response stream without enforcing a maximum number of bytes.

The timeout argument does not impose a total transfer deadline or file-size limit. A server can continue sending data while satisfying socket-read timeouts. The code also trusts Content-Length only for progress reporti ...[truncated 1299 chars]

Remediation
View remediation

Remediation Suggestions

  • Require HTTPS and validate result hosts against an allowlist of expected storage domains.
  • Disable or carefully validate redirects to prevent an approved URL from redirecting to an untrusted destination.
  • Reject responses whose declared Content-Length exceeds a configured maximum.
  • Independently track downloaded bytes and abort once the maximum is exceeded, including when Content-Length is missing or false.
  • Validate the expected media MIME type and, where practical, inspect file signatures.
  • Write to a temporary file inside the destination directory and remove it on every failure.
  • Atomically rename the temporary file only after size and type validation succeeds.
  • Apply identical controls to scripts/videogen.py.

Example byte-limit control:

python
max_bytes = 500 * 1024 * 1024
downloaded = 0

for chunk in resp.iter_content(chunk_size=8192):
    if not chunk:
        continue
    downloaded += len(chunk)
    if downloaded > max_bytes:
        raise ValueError("Download exceeds the configured size limit")
    temporary_file.write(chunk)
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

There is a clear description-behavior mismatch. The declared purpose is a high-level advertising and creative-production orchestration skill centered on generating campaign deliverables from briefs and using AI-HIVE APIs for asset-generation workflows. The supplied code instead implements a standalone ffmpeg-based video editing utility with subcommands for probe, trim, aspect conversion, mute, loudness normalization, and concat. While video editing could be loosely adjacent to ad production, this code does not implement the described business logic, workflow orchestration, API interactions, or deliverable generation. Its 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 a domain-specific marketing skill that accepts creative briefs, brand assets, product facts, budgets, channels, and schedules, then outputs structured ad-campaign artifacts such as creative propositions, channel matrices, main visuals, short-video scripts, asset batches, and acceptance rules. The supplied code does not implement any such business logic. Instead, it provides a reusable AI-Hive OpenAPI client and CLI for generic operations: querying user info, listing models, chatting with text models, generating images, generating videos, uploading media, polling tasks, and downloading outputs. The final skill-specific entrypoint (skill_main) is even narrower: it supports only image generation with a fixed model, plus task/upload/init. That means the actual primary purpose is generic AI-Hive media generation, not Creative Brief-to-campaign planning/execution. There are also undeclared capabilities unrelated to the declared specialized workflow, including text chat, video generation, model discovery, and user-info retrieval. While the description does mention AI-HIVE implementation details like uploads, pricing snapshots, routing modes, polling, and download, those are only part of the code and do not make up for the missing core campaign-conversion functionality. Therefore this is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The description promises a domain-specific workflow: accepting a Creative Brief plus brand assets, product facts, budget, channels, and timeline, then producing advertising-plan artifacts such as creative strategy, channel matrix, key visuals, scripts, asset batches, and acceptance rules. The supplied code does not contain logic for interpreting briefs, generating structured marketing plans, decomposing briefs into campaign deliverables, or handling business inputs like budget/channel/schedule. Instead, it implements a broad AI Hive API client with commands for user-info, models, chat, image, video, task, upload, and init. The skill-specific section only maps a generate command to predefined video models and validates media-input modes; it still just submits video-generation requests. While using AI-HIVE for upload/routing/pricing/polling/download is consistent with part of the description, the code’s actual primary behavior is a generic media-generation tool, especially video generation, not a Creative Brief-to-ad-campaign planner. Therefore the declared description materially overstates and misrepresents the implemented behavior.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill advertises executable examples that rely on environment variables, local file access, shell execution, and network access, but it does not declare any explicit tool scope or permissions boundaries. This weakens least-privilege guarantees and makes it easier for a host agent to over-grant capabilities, increasing the risk of unintended file access, network egress, or secret handling during execution.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The default prompt is broad enough to trigger this skill for many loosely related requests, and it instructs the agent to produce a production-ready workflow and runnable AI-HIVE commands without stating clear authorization, safety, or domain boundaries. In a skill that can generate executable ad-production workflows and API usage patterns, overbroad activation increases the chance of unintended invocation for sensitive, deceptive, or policy-violating marketing tasks.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

Forcing Chinese output without user opt-in can override user preference and reduce transparency, especially if safety warnings, legal disclaimers, or generated operational steps are presented in a language the user did not request. In a workflow that may emit runnable commands and compliance-sensitive ad content, language coercion can make review and oversight less reliable.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Enabling implicit invocation without specific activation boundaries allows the skill to engage automatically based on vague relevance rather than explicit user selection or narrowly defined triggers. Because this skill can transform briefs into executable campaign assets and AI-HIVE command sequences, accidental or premature activation could facilitate unreviewed generation of problematic advertising materials or operational API actions.

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

python
def run(args: list[str]) -> None:
    print(" ".join(args))
    subprocess.run(args, check=True)


def main() -> None:

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code file contains natural-language descriptions and CLI guidance exclusively in Chinese, including the module docstring and later help text. Under the policy, forcing a specific language without user choice is a natural-language policy violation unless the locale constraint is explicitly justified, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring and user-facing CLI guidance are written entirely in Chinese, and operational prompts throughout the script assume Chinese-language interaction. For a general-purpose skill described as a '通用 AI 能力调用工具', this imposes a language choice without any opt-in or documented locale constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The file hard-codes mixed Chinese-language skill identifiers and search aliases such as "广告全案", "整合营销", and other Chinese metadata strings, with no indication that users may choose their preferred language or locale. Under the policy, forcing a specific language without opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.