Back to skill

Security audit

Image Search

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real image-search tool, but local file searches can upload any readable file up to 32 MB to third-party image hosts without a runtime confirmation.

Review before installing if users may submit private photos, screenshots, documents, or arbitrary file paths. Prefer public image URLs only, or require explicit user confirmation before local uploads; the skill should validate image content and clearly warn that local files may become externally hosted.

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/lens_search.py:40
Finding

Automatic Disclosure of Local Files to Third-Party Image Hosting Services

Content
View full analysis
str: """Resolve image input to a public URL for SerpAPI. - URLs are returned as-is. - Local files are uploaded to a free image host. """ if image_path.startswith(("http://", "https://")): return image_path if not os.path.exists(image_path): print(f"Error: File not found: {image_path}", file=sys.stderr) sys.exit(1) file_size = os.path.getsize(image_path) if file_size > MAX_UPLOAD_BYTES: print(f"Error: File too large ({file_size / 1024 / 1024:.1f}MB > {MAX_UPLOAD_BYTES / 1024 / 1024:.0f}MB limit)", file=sys.stderr) sys.exit(1) # Prefer imgbb if key is available, otherwise freeimage.host imgbb_key = os.environ.get("IMGBB_API_KEY", "") if imgbb_key: url = _upload_imgbb(image_path, imgbb_key) if url: return url url = _upload_freeimage(image_path) if url: return url print("Error: Cannot upload local image. Provide an image URL or set IMGBB_API_KEY.", file=sys.stderr) sys.exit(1) def _read_as_base64(path: str) -> str: with open(path, "rb") as f: return base64.b64encode(f.read()).decode() def _upload_freeimage(image_path: str) -> str | None: """Upload to freeimage.host (free, no API key required).""" data = urllib.parse.urlencode({ "key": "6d207e02198a847aa98d0a2a901485a5", # freeimage public API key "action": "upload", "source": _read_as_base64(image_path), "format": "json", }).encode() req = urllib.request.Request("https://freeimage.host/api/1/upload", data=data) try: with urllib.request.urlopen(req, timeout=30 ...[truncated 4683 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documented purpose emphasizes Google Lens via SerpAPI, but the skill also uploads local images to third-party hosting services and may use an additional API path not reflected in the primary description. This creates a material transparency gap: users may provide sensitive local images without realizing they will be transmitted to unrelated external services.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The README states that local files are auto-uploaded to third-party image hosts, but it does not prominently warn about the privacy, confidentiality, and data-handling implications of sending user images to external services. In an agent-skill context, users may provide sensitive photos assuming local-only processing, so silent or under-emphasized third-party upload behavior can cause unintended disclosure.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README says the agent will automatically use the skill when users send images asking common phrases like 'what is this?', which is a broad trigger for a capability that uploads user-supplied images to external services and queries third-party APIs. In practice, this can cause the skill to activate without sufficiently specific user intent or informed consent, increasing the chance of unintended data exfiltration.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill declares environment and network-dependent behavior but does not define an explicit tool scope such as permissions or allowed-tools. In an agent setting, missing scope declarations weaken least-privilege controls and can allow broader execution than users or orchestrators expect.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Describing the skill as using Google Lens via SerpAPI without prominently disclosing that local images are first uploaded to other hosting providers obscures a significant data transfer step. That omission increases the chance of unintended exposure of private, copyrighted, or sensitive images.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Claiming that only SERPAPI_KEY is required is misleading when local-file support depends on third-party image hosting and may require IMGBB_API_KEY. In practice, this can cause operators to approve or deploy the skill without understanding its full external dependency and data-flow footprint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation does not clearly warn users that supplying a local image file may result in that file being uploaded to third-party services. In this skill's context, that is especially risky because users may submit personal photos, documents, or other sensitive images expecting only analysis through the named provider.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill claims to perform Google Lens searches via SerpAPI, but for local files it silently uploads the image to unrelated third-party hosting services first. This creates an undisclosed data-sharing path for user-provided images, which may expose sensitive or private content beyond the expected SerpAPI processing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

At the point local paths are accepted, the code proceeds toward uploading those files externally without an explicit warning that image contents will be disclosed to third-party hosts. In an image-search skill, users may reasonably expect analysis by SerpAPI/Google Lens, not publication or transfer to separate hosting providers.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code adds image-hosting functionality through freeimage.host and imgbb, which is broader than the narrowly described purpose of Google Lens via SerpAPI. Expanding data flow to extra third parties increases attack surface, privacy risk, and the chance that sensitive local files are transmitted to services the user did not anticipate.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
86% confidence
Finding

This line sends base64-encoded local image data to api.imgbb.com, constituting external transmission of potentially sensitive user content. External transmission is expected to some extent for a search skill, but this specific transfer is riskier because it goes to an auxiliary image host rather than the primary documented service.

Content

Scanner excerpt · scripts/lens_search.py (reported line 101)May include surrounding context.

python
"image": _read_as_base64(image_path),
    }).encode()

    req = urllib.request.Request("https://api.imgbb.com/1/upload", data=data)
    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            result = json.loads(resp.read())

Static analysis

No suspicious patterns detected.