Back to skill

Security audit

Local Image Search

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches local image search, but one search script can be tricked into running commands and the copy helper can duplicate arbitrary local files.

Review or fix this before installing. Do not pass untrusted search patterns to search_by_name.sh unless it is hardened with -- delimiters for fd and grep. Use copy_results.sh only after reviewing the result list and only with a destination you explicitly choose. Scope searches to specific folders because local photos and GPS metadata can be private.

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

Error
Location
scripts/search_by_name.sh:5
Finding

Argument Injection into fd Enables Unintended Command Execution

Content
View full analysis

Vulnerability Details

File Location: scripts/search_by_name.sh, lines 5-20
Vulnerability Type: Argument injection leading to command execution
Risk Level: High

Vulnerable Code

bash
PATTERN="$1"
DIR="${2:-$HOME}"

if [ -z "$PATTERN" ]; then
    echo "Usage: $0 <pattern> [directory]"
    echo "Example: $0 'screenshot' ~/Desktop"
    exit 1
fi

# Check if fd is available
if command -v fd &> /dev/null; then
    fd -e jpg -e jpeg -e png -e heic -e webp -e gif -e tiff -e raw "$PATTERN" "$DIR"
else
    # Fallback to find + grep
    find "$DIR" -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.heic" -o -iname "*.webp" -o -iname "*.gif" -o -iname "*.tiff" -o -iname "*.raw" \) 2>/dev/null | grep -i "$PATTERN"
fi

Technical Analysis

The user-controlled PATTERN value is passed to fd without an end-of-options delimiter. Shell quoting protects the value from shell word splitting and shell metacharacter expansion, but it does not stop fd from interpreting a value beginning with - as a command-line option.

This is security-sensitive because fd supports command-execution options such as --exec and --exec-batch. A crafted pattern can therefore alter the intended operation from a filename search into execution of another local command. The second script argument, nominally the search directory, may then be consumed by fd as the command or executable associated with the injected option.

The fallback branch has a related argument-parsing weakness: grep -i "$PATTERN" can interpret a dash-prefixed pattern as an option. This fallback issue can alter search behavior or expose unintended files, although the confirmed command-execution impact specifically applies to the fd branch.

Attack Path

  1. An attacker influences the filename pattern and directory arguments passed to search_by_name.sh.
  2. The target environment has fd insta ...[truncated 1179 chars]
Remediation
View remediation

Remediation Suggestions

Terminate fd option processing before passing user-controlled positional arguments:

bash
fd -e jpg -e jpeg -e png -e heic -e webp -e gif -e tiff -e raw -- "$PATTERN" "$DIR"

Apply the same defense to the fallback grep invocation:

bash
find "$DIR" -type f \( \
    -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o \
    -iname "*.heic" -o -iname "*.webp" -o -iname "*.gif" -o \
    -iname "*.tiff" -o -iname "*.raw" \
\) 2>/dev/null | grep -i -- "$PATTERN"

Additional hardening should include:

  1. Validate that DIR exists and is a directory before invoking the search tool.
  2. Reject unexpected control characters in search input.
  3. Run ShellCheck and add tests for patterns such as --exec, --exec-batch, -e, and --help.
  4. Execute the skill under a least-privileged account when processing arguments from untrusted sources.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared purpose is a local image search utility, but the supplied code does not search for images, use Spotlight or fd, inspect metadata, or filter by name/date/location. Instead, it performs file-copy operations on input paths and organizes results into a destination folder. File copying could be a supporting post-processing step in a larger search workflow, but as an isolated code chunk its behavior is materially different from the declared search functionality and introduces undeclared file-manipulation capability.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The code is related to local image discovery, so it is in the same general domain as the description. However, the declared description specifically claims fast local image search by name, date, location, or metadata using macOS Spotlight or fd. This code only enumerates all image files under a directory. Its Spotlight query is a generic content-type filter for images, not a user-driven search by name/date/location/metadata, and the fallback uses find rather than fd. That makes the implemented behavior materially narrower and somewhat different from the declared purpose.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This script adds a file-copying primitive that goes beyond a narrowly stated 'local image search' capability. Because it accepts arbitrary file paths from stdin and copies them to any user-supplied destination, it can be used to stage or duplicate local files in ways not clearly implied by the skill's purpose, increasing the risk of unintended data movement or abuse by other components.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The capability to copy search results is not clearly justified by a skill described as performing local image search, so it expands the attack surface beyond discovery into file manipulation. In an agent context, this mismatch is dangerous because a seemingly low-risk search tool can also duplicate sensitive local content to another folder without strong guardrails or clear disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill documents piping results into a copy script that writes files to another directory, but it does not clearly warn that this step performs filesystem modification. In an agent setting, understated write behavior can cause unintended copying of sensitive local images or clutter destination paths if invoked without clear user confirmation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The header comment and usage text claim the script accepts only 'today|week|month', but the case statement also implements a 'year' option and the error message lists it as valid. This is an intent/documentation mismatch because the inline documentation understates what the code actually supports.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.