Back to skill

Security audit

Photo Organizer

Security checks for vulnerabilities and agentic risk

Overview

This is mostly a photo organizer, but its undo feature can copy and delete files based on an untrusted manifest, and one install path pulls an unverified package.

Review before installing. Use the script only on directories you control, prefer preview first, avoid the unverified pip install path unless package ownership and version are verified, and do not run undo on an output directory if .photo-organizer-backup.json could have been modified by someone else.

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:21
Finding
Unverified Third-Party Package Installation Instruction## Vulnerability Details **File Location**: `SKILL.md`, lines 21-23 **Vulnerability Type**: Unverified and unpinned third-party dependency installation **Risk Level**: Medium ### Vulnerable Code ```bash # Method 2: Install as a Python package pip install photo-organizer ``` ### Technical Analysis The skill instructs users to install `photo-organizer` directly from the default Python Package Index without specifying an audited version, cryptographic hashes, or a verified source repository. The audited project does not contain Python packaging metadata that establishes a verifiable relationship between this source tree and the package resolved by that command. Package installation can execute package-controlled build and installation logic. Consequently, an unrelated, compromised, or dependency-confusion package published under the specified name could execute code with the privileges of the user running `pip`. ### Attack Path 1. An attacker publishes or compromises a package named `photo-organizer` on the package index used by the victim. 2. A user follows the installation instructions in `SKILL.md`. 3. `pip` resolves and downloads the attacker-controlled package because no trusted source, version, or hash is specified. 4. Package-controlled build or installation code executes locally. 5. The malicious package gains the ability to access or modify resources available to the installing user. ### Impact Assessment Successful exploitation can result in arbitrary code execution under the installing user's account. The accessible scope may include personal files, environment variables, API credentials, SSH configuration, and other resources available to that account. If installation is performed with administrative privileges, the impact may extend to system-wide compromise.
Remediation
## Remediation Suggestions - Remove the `pip install photo-organizer` instruction unless the package identity and ownership can be verified. - Publish official packaging metadata from the audited repository and link directly to the authoritative package and source repository. - Pin dependencies to reviewed versions and provide cryptographic hashes, such as through a hash-locked requirements file. - Recommend installation in an isolated virtual environment without administrative privileges. - Use a controlled package index or signed release artifacts where practical. - Document how users can verify release signatures, checksums, package ownership, and source provenance before installation.

T09 · Insecure Skill Coding Practices

Error
Location
photo_organizer.py:27
Finding
Untrusted Undo Manifest Allows Arbitrary File Copy and Deletion## Vulnerability Details **File Location**: `photo_organizer.py`, lines 27-30 and 137-153 **Vulnerability Type**: Unvalidated filesystem paths loaded from a writable rollback manifest **Risk Level**: High ### Vulnerable Code ```python def load_backup(self): if self.backup_file.exists(): with open(self.backup_file, 'r', encoding='utf-8') as f: self.backup_data = json.load(f) return self.backup_data ``` ```python def undo(self): backup = self.load_backup() if not backup: print("没有找到备份文件,无法撤销") return False reverse_mappings = {v: k for k, v in backup.items()} count = 0 for new_str, old_str in reverse_mappings.items(): new_path = Path(new_str) old_path = Path(old_str) if new_path.exists() and not old_path.exists(): copy2(new_path, old_path) new_path.unlink() print(f"撤销: {new_path.name} -> {old_path.name}") count += 1 ``` ### Technical Analysis The undo operation treats `.photo-organizer-backup.json` as a trusted description of filesystem operations. Each manifest key and value is converted directly into a `Path` without validating whether it is absolute, contains traversal components, resolves through a symbolic link, or remains within the expected input and output directories. The manifest normally maps an original path to an organized path. During undo, the mapping is reversed, after which the program copies the alleged organized file to the alleged original location and deletes the source. Because both paths are controlled by the manifest, a modified manifest can cause the program to move an arbitrary readable file to an attacker-selected writable destination. The checks only verify that the source exists and the destination does not exist. They do not establish that the paths were generated by a legitimate organization operation or that either path belongs ...[truncated 1486 chars]
Remediation
## Remediation Suggestions - Store relative path identifiers instead of unrestricted absolute filesystem paths. - Resolve every source and destination with `Path.resolve()` and verify containment under explicitly approved roots before performing any operation. - Reject absolute paths, parent-directory traversal, malformed entries, unexpected value types, and paths outside the configured input or output directory. - Detect and reject symbolic links in the manifest path and in relevant source, destination, and parent path components. - Authenticate rollback manifests, for example with an integrity-protected record stored in a user-private state directory. - Create manifests with restrictive permissions and use atomic file creation and replacement. - Before deletion, verify that the source corresponds to a file previously created by the organizer, using recorded metadata or a cryptographic digest. - Do not delete a source merely because a manifest references it. Separate restoration from deletion, or require explicit confirmation after displaying canonical paths. - Add tests covering absolute paths, `..` traversal, symlink redirection, malformed JSON structures, and mappings outside approved roots.
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • 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 (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The overall domain and primary purpose do match a photo organization utility, and there are no suspicious undeclared capabilities such as network access or unrelated data exfiltration. However, the declared description materially overstates two core features: location-based automatic classification and tagging. While the code can organize photos by date using EXIF or file modification time, its 'location' option does not actually use GPS metadata to group by place; it only changes the destination folder pattern to 'by-location/<year>'. Also, there is no implementation of tagging at all. Because these are prominent advertised capabilities rather than minor details, this is a description-behavior mismatch.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill describes operations that read from and write to the filesystem, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates an authorization ambiguity where an agent or platform may grant broader file access than users expect, increasing the risk of unintended file modification or data exposure during photo organization tasks.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The manifest description and main heading present the skill in Chinese only, which can impose a language requirement on users without opt-in. The policy for this category flags forced language or locale constraints unless the skill offers a choice or clearly justifies a region-specific limitation.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This file contains natural-language strings for the tool description, prompts, status messages, and CLI help exclusively in Chinese. Because the skill does not provide an opt-in language selection or justify a Chinese-only locale restriction, it violates the language/locale policy for natural-language behavior.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The manifest says the tool supports automatic classification and tagging by time and location. In code, the 'location' mode only places photos under 'by-location/<year>' and never interprets GPS metadata into location-based folders, while no tagging behavior exists anywhere in the file.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The command-line documentation explicitly presents 'location' as a real organization mode. However, get_folder_path() does not compute any place information from EXIF GPS data and simply returns output_dir/'by-location'/year, contradicting the documented behavior.

Intent-Code Divergence

Low
Confidence
95% confidence
Finding
Under '功能特性', the README uses the same enabled-feature format for '批量打标签' but annotates it as '计划中', while the manifest description says the skill supports automatic classification and tagging now. This creates a direct contradiction between the claimed current capability and the documented implementation status.

Intent-Code Divergence

Low
Confidence
78% confidence
Finding
The README's safety section states both that the tool defaults to copying instead of moving and that it 'automatically saves backups before execution.' For a copy-only organizer, automatic backup is a materially stronger claim and appears inconsistent with the rest of the documented behavior, which only discusses preview and undo at a high level. This is an intent/documentation divergence because the documentation presents a safety guarantee not otherwise supported within the described operations.

Static analysis

No suspicious patterns detected.