Back to skill

Security audit

Organise photos

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent photo-organizing helper, but it automatically installs unpinned Python packages and uses predictable /tmp files that later influence file moves or deletions.

Review before installing. Use an isolated virtual environment with pinned dependencies, avoid the automatic pip-install snippets, and verify the exact files to be moved or deleted before approving cleanup. Prefer moving rejected photos over permanent deletion.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:92
Finding
Automatic Installation of Unpinned Runtime Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:92-98`, `SKILL.md:162-171`, `SKILL.md:450-456`, and `SKILL.md:474` **Vulnerability Type**: `T08: Insecure Dependencies` **Risk Level**: Medium ### Vulnerable Code ```python try: from PIL import Image import numpy as np except ImportError: os.system("pip install Pillow numpy -q") from PIL import Image import numpy as np ``` ```python try: import cv2 import numpy as np from PIL import Image from PIL.ExifTags import TAGS import imagehash except ImportError: os.system("pip install opencv-python-headless Pillow imagehash numpy -q") import cv2 import numpy as np from PIL import Image from PIL.ExifTags import TAGS import imagehash ``` The prerequisite instructions also recommend installing mutable package names without version or integrity constraints: ```bash pip install Pillow numpy opencv-python-headless imagehash pip install rawpy ``` ### Technical Analysis The generated scripts automatically invoke `pip` when imports fail. The dependency names have no pinned versions or cryptographic hashes, and installation uses the Python environment's currently configured package index. The packages are then imported immediately. Python packages may execute arbitrary code during installation and import. Consequently, security depends on mutable third-party releases, the integrity of the configured index, and the absence of package-resolution manipulation. The installation is also not isolated from the Agent's existing Python environment. Suppressing installation output with `-q` reduces visibility into the package versions and sources selected. Automatic installation additionally occurs as a side effect of photo analysis rather than through a distinct, explicitly approved dependency setup step. ### Attack Path 1. An attacker compromises a dependency release, a configured package index, or the package-resolution/network path. 2. The skill run ...[truncated 931 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all automatic `pip install` calls from generated runtime scripts. 2. Declare dependencies in a reviewed lock file with exact versions and cryptographic hashes. 3. Install dependencies during a separate, explicit setup phase after obtaining user approval. 4. Use a dedicated virtual environment instead of modifying the Agent's global or existing Python environment. 5. Configure installation to use a trusted package repository and require hash verification, for example with `pip install --require-hashes`. 6. Record and display the exact selected versions and source repository instead of suppressing installation output. 7. Fail safely with a clear missing-dependency message when the environment is not prepared. 8. Regularly scan locked dependencies for known vulnerabilities and review updates before changing versions. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:269
Finding
Predictable Shared Temporary Files Permit Script or Analysis-State Tampering<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:131`, `SKILL.md:269-270`, `SKILL.md:290-293`, `SKILL.md:309-315`, `SKILL.md:342-348`, and `SKILL.md:477` **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: Medium ### Vulnerable Code The skill directs the Agent to create or execute scripts at predictable paths: ```bash python3 /tmp/detect_bad_exposure.py "$FOLDER" 0.05 0.95 ``` ```bash python3 /tmp/analyze_photos.py "$FOLDER" 80 3 8 ``` Analysis output is written to a fixed shared path: ```python with open("/tmp/photo_analysis.json", "w") as fout: json.dump(output, fout, indent=2, ensure_ascii=False) ``` Subsequent file-management workflows trust data read from the same predictable file: ```python import json, shutil, os from pathlib import Path data = json.load(open("/tmp/photo_analysis.json")) FOLDER = "PATH_TO_FOLDER" for r in data["photos"]: if r.get("blurry"): src = Path(r["path"]) # delete: src.unlink() # move: shutil.move(str(src), os.path.join(FOLDER, "_rejected_blur", src.name)) ``` ```python import json, shutil, os from pathlib import Path data = json.load(open("/tmp/photo_analysis.json")) # Group photos by burst_group groups = {} for r in data["photos"]: g = r.get("burst_group") if g: groups.setdefault(g, []).append(r) for g_idx, members in groups.items(): for r in members: if not r.get("burst_best"): src = Path(r["path"]) # delete: src.unlink() # or move to _burst_extras/ ``` The documented cleanup instruction confirms that the fixed path is intended to be reused: ```text /tmp/photo_analysis.json — full analysis results; clean up after: rm /tmp/photo_analysis.json ``` ### Technical Analysis The skill uses fixed names in the globally shared `/tmp` directory for executable Python scripts and analysis state. It does not require secure exclusive creation, restrictive permissions, ownership verification ...[truncated 2714 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a private per-run directory with Python's `tempfile.TemporaryDirectory()` or `mkdtemp()` rather than fixed paths in `/tmp`. 2. Set restrictive permissions so only the Agent account can access the temporary directory and files. 3. Create files atomically and exclusively; reject existing paths and symbolic links. 4. Keep executable script content under trusted skill control, or execute trusted in-memory/module code instead of writing a predictable script into a shared directory. 5. Store the generated analysis path in per-run state and pass it explicitly to later processing steps. 6. Before acting on an analysis entry: - Resolve the source with `Path.resolve()`. - Verify that it is a regular file. - Confirm that its canonical path is beneath the canonical selected photo directory. - Reject symbolic links and paths containing traversal outside that directory. - Verify that the file is one of the photos scanned during the current run. 7. Bind the JSON to the current run using a random identifier and, where appropriate, an integrity check or authenticated in-memory state. 8. Revalidate and redisplay the exact canonical files immediately before any move or deletion. 9. Preserve the existing explicit-confirmation requirement and prefer moving files to a private rejection folder over permanent deletion. 10. Remove the private temporary directory automatically in a `finally` block when processing completes. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • 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 (3)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
`pip install rawpy` — add rawpy support to detect_bad_exposure.py for RAW files

### Temp Files
- `/tmp/photo_analysis.json` — full analysis results; clean up after: `rm /tmp/photo_analysis.json`

### Folder Safety
- Never delete files without explicit user confirmation
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The skill's Python snippet automatically runs `pip install Pillow numpy -q` via `os.system(...)` when imports fail. That gives the skill package installation and shell execution capability during normal use, which expands its privileges beyond simple photo organization and introduces supply-chain risk from downloading and executing external code at runtime.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
The blur/burst analysis script also auto-installs packages (`opencv-python-headless`, `Pillow`, `imagehash`, `numpy`) by invoking `pip` through the shell. This creates a runtime supply-chain exposure and permits networked code retrieval/execution in a skill whose purpose is local photo analysis, making compromise of the environment more plausible if dependency sources are tampered with or unintended packages are resolved.

Static analysis

No suspicious patterns detected.