Back to skill

Security audit

Image Deduplicator

Security checks for vulnerabilities and agentic risk

Overview

This is a local image cleanup skill that can delete or move files only when the user explicitly chooses those actions, with no hidden or unrelated behavior found.

Use the listing mode first, review the reported groups, keep backups before deletion, and prefer moving duplicates to a fresh empty folder. Install the Python dependencies in a virtual environment and pin versions if reproducibility matters.

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

Note
Location
SKILL.md:51
Finding
Unpinned Third-Party Dependencies Installed Without Integrity Verification## Vulnerability Details **File Location**: `SKILL.md`, line 51 **Vulnerability Type**: Supply-chain exposure through mutable dependencies **Risk Level**: Low ### Vulnerable Code ```bash pip install pillow imagehash ``` ### Technical Analysis The documented installation command installs the latest available versions of `pillow` and `imagehash` without version constraints or package integrity hashes. Consequently, the code installed by a user can differ from the dependencies that were available when the Skill was audited. The package names correspond to legitimate dependencies, and the audited project contains no evidence that they are currently malicious. Nevertheless, the installation process does not provide reproducibility or protect against a compromised package release, registry account takeover, or an unexpectedly incompatible future version. Python packages and their installation processes can execute code with the privileges of the user performing the installation. ### Attack Path 1. An attacker compromises a dependency maintainer account, distribution infrastructure, or a future dependency release. 2. The attacker publishes a malicious version under one of the package names used by the installation command. 3. A user follows the documented command after the malicious release becomes the latest matching version. 4. `pip` downloads and installs the altered package without checking a project-maintained version or expected artifact hash. 5. Malicious package code executes during installation or when `dedupe.py` imports and uses the dependency. ### Impact Assessment Successful exploitation could execute code with the privileges of the account running `pip` or the deduplication script. Depending on those privileges, this could expose accessible files, alter user data, or compromise the local Python environment. The scope is limited by the installing user's operating-system permissions. No direct compromise or malic ...[truncated 51 chars]
Remediation
## Remediation Suggestions - Define reviewed dependency versions in a dedicated requirements or lock file. - Pin exact versions rather than accepting whichever release is current at installation time. - Record and verify distribution hashes with a command such as: ```bash python -m pip install --require-hashes -r requirements.txt ``` - Generate hashes only from trusted package artifacts and review dependency updates before changing the lock file. - Use a virtual environment with minimal privileges and avoid installing the dependencies as an administrator or root user. - Add automated dependency vulnerability and provenance checks to the release process.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/dedupe.py:145
Finding
Predictable Move Destinations Can Overwrite Existing Files## Vulnerability Details **File Location**: `scripts/dedupe.py`, lines 145-160 **Vulnerability Type**: Unchecked destination collision during destructive file operation **Risk Level**: Medium ### Vulnerable Code ```python elif args.action == "move": output_dir = args.output or "duplicates" os.makedirs(output_dir, exist_ok=True) moved = 0 for i, files in enumerate(duplicates.values(), 1): # Keep first, move rest for file_path in files[1:]: try: basename = os.path.basename(file_path) dest = os.path.join(output_dir, f"dup_{i}_{basename}") shutil.move(file_path, dest) moved += 1 print(f"Moved: {file_path} -> {dest}") except Exception as e: print(f"Error moving {file_path}: {e}") print(f"\nMoved {moved} files to {output_dir}/") ``` ### Technical Analysis The destination filename is generated deterministically from the duplicate-group number and source basename. The code neither checks whether `dest` already exists nor creates the destination exclusively. When the destination resolves to an existing file, `shutil.move()` may replace that file, depending on the operating system and destination type. A collision can arise from a file already present in the user-selected output directory. It can also arise naturally when multiple files in the same duplicate group have the same basename but originate from different source subdirectories; those files receive the same `dup_{i}_{basename}` destination. Although grouped files are treated as duplicates, perceptual-hash equality does not prove byte-for-byte identity. Overwriting one moved item with another can therefore destroy a distinct source file. There is no rollback, collision warning, or confirmation for the individual replacement. ### Attack Path 1. The attacker can write to, or otherwise i ...[truncated 1059 chars]
Remediation
## Remediation Suggestions - Check destination existence before every move and refuse to replace an occupied path. - Generate collision-resistant destination names while preserving the extension, such as by appending a counter or UUID. - Use exclusive destination creation or another atomic no-overwrite mechanism to prevent time-of-check/time-of-use races. - Do not rely only on `os.path.exists()` followed by `shutil.move()`, because another process can create the destination between those operations. - Resolve and validate the output directory, and ensure it is not unexpectedly shared with an untrusted user. - Report every collision to the user and leave the source untouched. - Consider preserving the source-relative directory structure rather than reducing every source path to its basename. - For destructive operations, record a manifest and support rollback or require explicit confirmation of the final source-to-destination mapping.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (1)

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly documents a destructive delete action for duplicate or similar images without warning users about irreversible data loss or the possibility of false positives, especially when similarity thresholds below exact matching are used. In an agent context, users may trust the tool and invoke deletion on large folders, causing unintended removal of valuable images.

Static analysis

No suspicious patterns detected.