Back to skill

Security audit

Image Quality Filter

Security checks for vulnerabilities and agentic risk

Overview

This image-cleaning skill is coherent, but it can delete or move files in bulk and has an unsafe move path that may overwrite images without enough warning.

Review this skill before installing if your image folders contain originals or important datasets. Use the default list action first, test on a copy or small sample, avoid move destinations that may already contain same-named files, and only delete after reviewing the reported images and keeping backups.

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)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/quality_filter.py:204
Finding
Destination File Overwrite During Move Operations<![CDATA[ ## Vulnerability Details **File Location**: `scripts/quality_filter.py:204-207` **Vulnerability Type**: Unsafe file move with destination filename collisions **Risk Level**: Medium ### Vulnerable Code ```python basename = os.path.basename(r['path']) dest = os.path.join(output_dir, basename) shutil.move(r['path'], dest) moved += 1 ``` ### Technical Analysis The recursive scanner can discover files with identical basenames in different source subdirectories. During a move operation, the code discards each source file's relative directory structure and places every low-quality image directly into one output directory. The destination path is not checked for an existing file and is not assigned a collision-resistant name. On platforms where the underlying move or rename operation replaces an existing destination, a later image can silently overwrite an earlier image or a file that existed in the output directory before the operation. The move action does not require confirmation, unlike the delete action. This increases the likelihood that data loss will occur without the user being given an opportunity to review the operation. ### Attack Path 1. Create two subdirectories under the scanned directory. 2. Place a low-quality image with the same basename, such as `photo.jpg`, in each subdirectory. 3. Alternatively, place an existing `photo.jpg` in the selected output directory. 4. Run the tool with `scan <directory> --action move --output <output-directory>`. 5. Both source files resolve to `<output-directory>/photo.jpg`. 6. Depending on platform filesystem semantics, a subsequent `shutil.move` replaces the existing destination. 7. The previously moved or pre-existing destination file is lost. ### Impact Assessment The issue can cause unintended and potentially irreversible loss of image files. Its scope is limited to files writable by the account executing the script and to destination names derived from identified low-quality images. It does not ...[truncated 113 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Preserve each source file's path relative to the scanned root instead of flattening all files into one directory. - Before moving a file, explicitly test whether the destination already exists and refuse to overwrite it. - Generate a unique destination name when a collision occurs, such as by adding a counter or a cryptographically strong content-derived suffix. - Prefer an operation that enforces exclusive destination creation rather than relying on platform-specific `shutil.move` overwrite behavior. - Add a confirmation or dry-run summary for move operations. - Record collision decisions and failures in the output so users can verify that every source file was handled safely. Example defensive logic: ```python basename = os.path.basename(r['path']) dest = os.path.join(output_dir, basename) if os.path.exists(dest): stem, suffix = os.path.splitext(basename) counter = 1 while os.path.exists(dest): dest = os.path.join(output_dir, f"{stem}_{counter}{suffix}") counter += 1 shutil.move(r['path'], dest) moved += 1 ``` ]]>

T08 · Insecure Dependencies

Note
Location
SKILL.md:57
Finding
Unpinned Third-Party Dependency Installation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:57` **Vulnerability Type**: Non-reproducible dependency installation from mutable package releases **Risk Level**: Low ### Vulnerable Code ```bash pip install pillow numpy opencv-python ``` ### Technical Analysis The documented installation command installs the latest versions available for three third-party packages without version constraints, integrity hashes, or a lock file. The package names are consistent with the implementation, and the reviewed project does not specify a suspicious repository or known typosquatted package. Nevertheless, installations are not reproducible and automatically trust whatever releases the package index resolves at installation time. If a future package release is compromised, withdrawn and replaced, or introduces an incompatible or insecure change, users following the documented command may install and execute that release. Python packages can execute build or installation logic and are subsequently imported by the application. ### Attack Path 1. A user follows the installation command in `SKILL.md`. 2. `pip` resolves the current package versions rather than a set of previously reviewed versions. 3. A compromised or unexpectedly changed release is downloaded from the configured package index. 4. Package-controlled installation or import-time code runs with the permissions of the installing or executing user. 5. The resulting impact depends on the behavior of the compromised dependency and the privileges under which installation occurs. No evidence was found that the currently named packages or this project intentionally perform such an attack; this finding concerns the absence of dependency version and integrity controls. ### Impact Assessment A compromised dependency could potentially execute code with the privileges of the user running `pip` or the image filtering script. This could affect files, credentials, and other resources accessible to that ac ...[truncated 149 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin every direct dependency to a reviewed version. - Generate and commit a lock or constraints file that includes transitive dependencies. - Include cryptographic hashes and install with `pip --require-hashes`. - Regularly scan pinned dependencies for known vulnerabilities and update them through a controlled review process. - Install dependencies in an isolated virtual environment under a non-privileged account. - Use a trusted package index explicitly where deployment policy requires one. Example installation approach: ```bash python -m pip install --require-hashes -r requirements.txt ``` The `requirements.txt` file should contain reviewed exact versions and hashes for all direct and transitive dependencies. ]]>
Vulnerability Patterns
  • 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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly advertises a destructive 'delete' action for low-quality images but does not provide any warning, confirmation step, or guidance about irreversible data loss. In a dataset-cleaning context, users may assume the filter is reliable and accidentally delete valuable originals or misclassified images at scale.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The usage example directly instructs users to run a delete action on a path of images without any cautionary note, dry-run guidance, or confirmation mechanism. Example commands are high-trust copy/paste targets, so presenting destructive behavior this way materially increases the risk of accidental bulk data loss.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The script is presented as an image quality detector/filter, but it also supports destructive actions that delete files or move them out of place. In an agent or skill context, that mismatch increases the risk that a user or orchestrator invokes it expecting analysis only, leading to unintended data loss across recursively scanned directories.

Missing User Warnings

Low
Confidence
87% confidence
Finding
The example output states that low-quality images were removed, normalizing destructive behavior without explaining the data impact or possibility of misclassification. While less severe than an executable delete example, it still conditions users to expect silent removal as standard behavior.

Static analysis

No suspicious patterns detected.