Back to skill

Security audit

ChatGPT Image Handoff

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed image-handoff workflow that uses local files and optional approved ChatGPT browser interaction, with no evidence of hidden exfiltration, destructive behavior, or persistence beyond its runtime handoff state.

Install only if you are comfortable with a workflow that may send reviewed prompts or approved reference images to ChatGPT through your authenticated browser. Keep handoff directories out of public commits, review file lists before confirmation, and use reasonable image dimensions until explicit size limits are added.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/handoff_common.py:48
Finding

Unbounded Image Dimensions Permit Resource Exhaustion

Content
View full analysis

Vulnerability Details

File Location: scripts/handoff_common.py:48-55
Vulnerability Type: Unrestricted resource allocation from user-controlled image dimensions
Risk Level: Medium

Vulnerable Code

python
def parse_dimensions(value: str) -> tuple[int, int]:
    normalized = value.lower().replace(" ", "")
    parts = normalized.split("x", 1)
    if len(parts) != 2:
        raise ValueError(f"Invalid dimensions '{value}', expected WIDTHxHEIGHT")
    width, height = int(parts[0]), int(parts[1])
    if width <= 0 or height <= 0:
        raise ValueError(f"Dimensions must be positive: {value}")
    return width, height

The resulting dimensions are subsequently used in resource-intensive Pillow operations, including image resizing in scripts/ingest_images.py:66-73 and canvas/image processing in scripts/render_mixed_overlay.py:256-286.

Technical Analysis

parse_dimensions() only verifies that the supplied width and height are positive integers. It does not impose limits on either dimension or on the total pixel count calculated as width * height.

Dimensions originate from the user-controlled JSON specification or mixed-overlay plan. Values such as 1000000x1000000 therefore pass validation. Downstream Pillow operations may then attempt to resize an image or allocate a canvas with one trillion pixels. Depending on image mode and intermediate buffers, this can require multiple terabytes of memory and substantial CPU or disk resources.

Although Pillow may reject some extreme values or terminate with an allocation error, relying on library-specific failure behavior does not provide a reliable application-level resource boundary.

Attack Path

  1. An attacker or untrusted workflow input supplies a handoff specification or overlay plan containing an extremely large positive dimension, such as 1000000x1000000.
  2. parse_dimensions() accepts the value because both integers are positive.
  3. The workflow reaches an image operati ...[truncated 1032 chars]
Remediation
View remediation

Remediation Suggestions

  1. Define explicit limits for each dimension and total pixel count. For example:
python
MAX_IMAGE_WIDTH = 16384
MAX_IMAGE_HEIGHT = 16384
MAX_IMAGE_PIXELS = 100_000_000

def parse_dimensions(value: str) -> tuple[int, int]:
    normalized = value.lower().replace(" ", "")
    parts = normalized.split("x", 1)
    if len(parts) != 2:
        raise ValueError(f"Invalid dimensions '{value}', expected WIDTHxHEIGHT")

    width, height = int(parts[0]), int(parts[1])
    if width <= 0 or height <= 0:
        raise ValueError(f"Dimensions must be positive: {value}")
    if width > MAX_IMAGE_WIDTH or height > MAX_IMAGE_HEIGHT:
        raise ValueError(f"Dimensions exceed supported limits: {value}")
    if width * height > MAX_IMAGE_PIXELS:
        raise ValueError(f"Image pixel count exceeds supported limit: {value}")

    return width, height
  1. Apply the same limits before every Pillow allocation or resize operation, rather than relying only on validation during initial handoff preparation.

  2. Configure and enforce an appropriate PIL.Image.MAX_IMAGE_PIXELS policy for inbound images, and treat decompression-bomb warnings as errors where appropriate.

  3. Validate source image file size and decoded pixel count before copying, converting, resizing, or adding it to a contact sheet.

  4. Use process-level resource controls, such as memory limits, CPU timeouts, and disk quotas, as defense in depth.

  5. Add negative tests covering excessive width, excessive height, excessive total pixel count, malformed dimensions, and large inbound images.

Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

Here the mismatch centers on presenting the skill as a full orchestration layer while the implementation appears limited to overlay repair/render reporting. Such overclaiming is dangerous because users may send data, approve workflows, or rely on provenance guarantees believing the skill performs review, routing, and state management steps that are not actually executed.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

Here the mismatch centers on presenting the skill as a full orchestration layer while the implementation appears limited to overlay repair/render reporting. Such overclaiming is dangerous because users may send data, approve workflows, or rely on provenance guarantees believing the skill performs review, routing, and state management steps that are not actually executed.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Here the mismatch centers on presenting the skill as a full orchestration layer while the implementation appears limited to overlay repair/render reporting. Such overclaiming is dangerous because users may send data, approve workflows, or rely on provenance guarantees believing the skill performs review, routing, and state management steps that are not actually executed.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The QA checklist explicitly requires checking 'exact Chinese' text, which imposes a specific language expectation in the workflow. The document does not present this as optional, user-selected, or region-specific, so it appears to enforce a locale/language constraint without opt-in.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The default prompt includes an activation phrase that can be invoked broadly without clear preconditions, which increases the chance of accidental or unauthorized routing into a high-capability workflow. In this skill’s context, that workflow may involve browser-based handoff, external generation backends, and asset import/resume behavior, so ambiguous triggering expands the attack surface and can cause unintended execution paths.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This script updates and saves jobs.json, which changes persistent user/project state, but the code provides no explicit warning before the write and no comment or docstring disclosing that it will modify the handoff state file. The only visible output is the selected backend and reason after the write, so the file modification itself is not clearly disclosed at the point of action.

Content

No source excerpt is available for this finding.