Back to skill

Security audit

Image Assets Resize — 图片素材尺寸延展

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its image-generation purpose, but it needs review because it can send user images and API keys to configurable endpoints, run unverified helper code, and store sensitive configuration and brand history locally.

Install only if you are comfortable with this skill sending marketing images and prompts to the configured model provider or gateway. Prefer environment variables over plaintext API keys, avoid custom API base URLs unless you trust and control them, do not use sensitive unreleased assets without checking provider handling, and treat the GPT Image helper and optional upscaler installer as review-required because they execute code outside the audited skill package.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/spec_manager.py:350
Finding

Arbitrary File Read and Write Through Unsanitized Brand Names

Content
View full analysis
dict: """Load brand design-language configuration.""" brand_file = _brand_dir() / f"{brand_name}.json" if brand_file.exists(): return json.loads(brand_file.read_text(encoding="utf-8")) return { "name": brand_name, "colors": [], "fonts": [], "style_notes": "", "design_patterns": [], "avoid_patterns": [], "sample_count": 0, "generations": [], } def save_brand(brand_data: dict) -> None: """Save brand design-language configuration.""" brand_dir = _brand_dir() brand_dir.mkdir(parents=True, exist_ok=True) brand_file = brand_dir / f"{brand_data['name']}.json" brand_file.write_text( json.dumps(brand_data, ensure_ascii=False, indent=2), encoding="utf-8", ) ``` ### Technical Analysis The user-controlled `--brand` argument is passed to `load_brand()` and ultimately used directly as part of a filesystem path. The code does not reject absolute paths, parent-directory components, or path separators. With `pathlib`, joining a base directory to an absolute path discards the base directory. Relative components such as `../` can also escape the intended `~/.content-marketing/brands` directory after path resolution. The same unsafe value is retained in the brand data's `name` field and later passed to `save_brand()`. Consequently, the vulnerable flow supports both reading an existing JSON file and writing generation records to a location outside the intended state directory. ### Attack Path 1. An attacker invokes the Skill with a crafted brand value, such as: ```text --brand ../../../../tmp/attacker-controlled ``` 2. `record_generation()` calls `load_brand(brand_name)`. 3. `load_brand()` constructs ...[truncated 947 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/backend.py:208
Finding

API Credentials and User Images Can Be Transmitted to Untrusted or Plaintext Endpoints

Content
View full analysis
dict: result = { "success": False, "output_path": output_path, "error": None, "time_elapsed": 0, } start = time.time() api_key = get_api_key(self.config) base_url = get_base_url(self.config) if not api_key: return {**result, "error": "API key is not configured"} endpoint = f"{base_url}/chat/completions" try: import urllib.request import urllib.error data = json.dumps(body, ensure_ascii=False).encode("utf-8") req = urllib.request.Request( endpoint, data=data, headers={ "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", }, method="POST", ) with urllib.request.urlopen(req, timeout=timeout) as resp: result["time_elapsed"] = round(time.time() - start, 1) raw = resp.read().decode("utf-8") ``` The optional verification path has equivalent behavior: ```python base_url = os.environ.get( "GPT_IMAGE2_BASE_URL", "https://api.openai.com/v1", ) endpoint = f"{base_url.rstrip('/')}/chat/completions" req = urllib.request.Request( endpoint, data=body, headers={ "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", }, method="POST", ) with urllib.request.urlopen(req, timeout=60) as resp: raw = resp.read().decode("utf-8") ``` ### Technical Analysis Uploading a reference image to an AI image service is necessary for the declared functionality and is documented by the Skill. The vulnerability is theref ...[truncated 1774 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/backend.py:58
Finding

API Keys Are Persisted in Plaintext Without Explicit Permission Hardening

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/upscaler.py:32
Finding

External Executable Archive Is Installed Without Cryptographic Verification

Content
View full analysis
tuple[bool, str]: """Download and install Real-ESRGAN.""" exe = _find_esrgan_exe() if exe and _check_esrgan_models(exe.parent): return True, "Ready" if not exe: zip_path = BIN_DIR / "realesrgan.zip" try: BIN_DIR.mkdir(parents=True, exist_ok=True) subprocess.run( ["curl", "-fsSL", "-o", str(zip_path), ESRGAN_ZIP_URL], capture_output=True, timeout=120, check=True, ) with zipfile.ZipFile(zip_path, "r") as zf: zf.extractall(str(ESRGAN_DIR)) zip_path.unlink() exe = _find_esrgan_exe() if not exe: return False, "Installation failed: executable not found" except Exception as e: if zip_path.exists(): zip_path.unlink() return False, f"Download failed: {e}" return True, "Binary installed; model files are missing" ``` ### Technical Analysis The optional installer downloads a native executable archive from a fixed GitHub release URL and extracts it into a local executable directory. HTTPS provides transport protection, but the Skill does not verify a pinned digest or cryptographic signature. As a result, the effective binary is trusted solely because it was returned by the remote URL. Compromise of the upstream release, publisher account, delivery path, or downloaded artifact could substitute malicious native code without detection. The archive is also extracted ...[truncated 1234 chars]
Remediation
View remediation

T07 · Tool Hijacking and Spoofing

Error
Location
scripts/backend.py:143
Finding

Unaudited External Helper Script Is Executed With the Full Process Environment

Content
View full analysis
str: script_dir = Path(__file__).parent.resolve() candidates = [ str( script_dir.parent.parent / "gpt-image-2-api" / "scripts" / "gpt_image2.py" ), str( script_dir.parent / "gpt-image-2-api" / "scripts" / "gpt_image2.py" ), ] for c in candidates: if os.path.exists(c): return c return candidates[0] ``` ```python def _run(self, cmd: list[str], timeout: int, output_path: str = "") -> dict: result = { "success": False, "output_path": output_path, "error": None, "time_elapsed": 0, } start = time.time() try: proc = subprocess.run( cmd, capture_output=True, text=True, encoding="utf-8", env={**os.environ, "PYTHONIOENCODING": "utf-8"}, timeout=timeout + 30, ) ``` ### Technical Analysis The GPT Image backend does not implement the API call within the audited package. Instead, it searches predictable sibling locations for `gpt_image2.py` and executes the first existing file. The external script is absent from the audited project. Its version, ownership, integrity, and contents are not checked. Any party able to create or replace a file at one of the candidate paths can cause attacker-controlled Python code to run when the GPT backend is invoked. The subprocess also receives a complete copy of `os.environ`. This may include API keys and unrelated credentials that are not required for image generation, increasing the consequences of helper-script substitution. Using a command argument list prevents shell metacharacter injectio ...[truncated 1095 chars]
Remediation
View remediation
Vulnerability Patterns
  • 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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (33)

Tainted flow: 'req' from os.environ.get (line 160, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/generate_image.py (reported line 169)May include surrounding context.

python
method="POST",
        )

        with urllib.request.urlopen(req, timeout=60) as resp:
            raw = resp.read().decode("utf-8")

        resp_data = json.loads(raw)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The skill description materially overstates or misstates behavior, including AI self-checks, learning/accumulation features, and operational behaviors around configuration and secret handling. Security-relevant mismatches reduce informed consent and can cause users to expose images, prompts, or API credentials under false assumptions about what the skill actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill description materially overstates or misstates behavior, including AI self-checks, learning/accumulation features, and operational behaviors around configuration and secret handling. Security-relevant mismatches reduce informed consent and can cause users to expose images, prompts, or API credentials under false assumptions about what the skill actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill description materially overstates or misstates behavior, including AI self-checks, learning/accumulation features, and operational behaviors around configuration and secret handling. Security-relevant mismatches reduce informed consent and can cause users to expose images, prompts, or API credentials under false assumptions about what the skill actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill description materially overstates or misstates behavior, including AI self-checks, learning/accumulation features, and operational behaviors around configuration and secret handling. Security-relevant mismatches reduce informed consent and can cause users to expose images, prompts, or API credentials under false assumptions about what the skill actually does.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill processes uploaded images and prompts through external model APIs, yet the description does not prominently warn users that their content may be transmitted to third-party services. In this context, the inputs are likely to be marketing assets, posters, or branded images that may contain confidential campaign material, making undisclosed external transmission a meaningful privacy and confidentiality risk.

Content

No source excerpt is available for this finding.

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

python
try:
            proc = subprocess.run(
                cmd, capture_output=True, text=True, encoding="utf-8",
                env={**os.environ, "PYTHONIOENCODING": "utf-8"},
                timeout=timeout + 30,
            )
            result["time_elapsed"] = round(time.time() - start, 1)

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

python
prompt += f" 场景:{scene}。"
    if extra:
        prompt += f" 额外要求:{extra}"
    return prompt


def build_generate_prompt(

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The manifest advertises a skill that uses environment variables, file read/write, network access, and shell execution, but it does not declare any explicit tool scope such as permissions or allowed-tools. That weakens least-privilege controls and makes it easier for the skill to access sensitive files, invoke commands, or transmit data beyond what users expect.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill documents persistent storage of custom specs, feedback, and brand-related learning data under the user's home directory, but this retention is not clearly surfaced as a privacy/data-handling warning in the manifest. Persistent local storage can accumulate sensitive business assets, branding guidance, or user-provided content beyond the immediate task lifecycle.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger text says the skill applies whenever a user needs to adapt or batch-produce image assets from reference posters/KV images, which is a broad natural-language condition rather than a specific invocation phrase or constrained context. It does not provide explicit trigger phrases, exclusions, or negative examples, so it could overlap with many ordinary design-related requests and cause unintended invocation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation states that generated assets and learned brand data may be stored persistently, but it does not present this as a clear user warning or consent point. Because this skill handles creative assets and brand language, silent retention can expose sensitive commercial information to later access on the same system.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The entire skill reference is written only in Chinese and does not indicate that users may request another language or that the content is limited to a China-specific audience. Because the file also covers overseas platforms, this creates a language/locale constraint that is not clearly justified or opt-in.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The manifest describes a skill for generating correctly sized image assets from reference images, but this file also implements a standalone configuration manager with persistent local state under ~/.content-marketing and interactive credential collection. That capability goes beyond the core asset-generation function and is not explicitly justified by the manifest description.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · SKILL.md (reported line 331)May include surrounding context.

md
DEFAULT_CONFIG = {
    "backend": "gpt-image-2",
    "base_url": "https://api.openai.com/v1",
    "api_key_env": "OPENAI_API_KEY",
    "model": {
        "gpt-image-2": "gpt-image-2",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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/backend.py (reported line 35)May include surrounding context.

python
DEFAULT_CONFIG = {
    "backend": "gpt-image-2",
    "base_url": "https://api.openai.com/v1",
    "api_key_env": "OPENAI_API_KEY",
    "model": {
        "gpt-image-2": "gpt-image-2",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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/generate_image.py (reported line 157)May include surrounding context.

python
DEFAULT_CONFIG = {
    "backend": "gpt-image-2",
    "base_url": "https://api.openai.com/v1",
    "api_key_env": "OPENAI_API_KEY",
    "model": {
        "gpt-image-2": "gpt-image-2",

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest describes calling image models to generate resized assets, but this backend shells out to another Python CLI using subprocess.run. Spawning external processes is a broader capability than directly invoking model APIs and is not clearly justified by the declared purpose alone.

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

python
result = {"success": False, "output_path": output_path, "error": None, "time_elapsed": 0}
        start = time.time()
        try:
            proc = subprocess.run(
                cmd, capture_output=True, text=True, encoding="utf-8",
                env={**os.environ, "PYTHONIOENCODING": "utf-8"},
                timeout=timeout + 30,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The edit path reads a local image, base64-encodes it, and sends it in the request body to a remote /chat/completions endpoint. While network transmission is intrinsic to an image-generation backend, this code path lacks any direct disclosure via print/log/comment/docstring that local image data will be uploaded during editing.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The setup flow allows users to enter an API key and persists it in plaintext JSON under the home directory, and the display command reveals portions of the key on screen. Plaintext local secret storage increases the chance of credential theft by other local users, malware, backups, or accidental disclosure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The setup wizard, configuration display, help descriptions, and error/status messages are presented only in Chinese. This creates a locale policy issue because the skill does not provide any opt-in, selection mechanism, or documented justification for restricting the interface to a single language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

Natural-language strings in the docstring, CLI descriptions, and prompt-building logic assume Chinese-language usage, and generated prompts are composed in Chinese by default. The file does not offer user language selection or explain that the skill is intentionally limited to a Chinese-language workflow.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

When --verify is enabled, the script base64-encodes the generated image and sends it to an external chat completion API for review, but the CLI does not clearly warn that image contents will leave the local environment. If users process proprietary marketing assets, unreleased campaign materials, or regulated images, this can cause unintended data disclosure to a third-party service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code persists brand configuration data to files under the user's home directory, and related callers store prompts, output paths, feedback, and ratings as part of the skill's self-learning behavior. The file contains no confirmation prompt, visible user-facing notice, or warning comment/docstring disclosing that user-provided content and feedback will be retained locally.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.