Back to skill

Security audit

Music Tagger

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a prototype music tagging tool, but its documented capabilities overstate what it does and its undo/backup handling can copy or delete unintended local files if backup data is tampered with.

Treat this as a prototype, not a reliable music tag editor. Run it only on test copies of music, use preview first, avoid shared or untrusted output directories, do not rely on undo unless you trust the backup file, and pin/review any dependencies before installing them.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
music_tagger.py:160
Finding
Tamperable Backup File Enables Arbitrary File Copy and Deletion<![CDATA[ ## Vulnerability Details **File Location**: `music_tagger.py:25-28`, `music_tagger.py:160-179` **Vulnerability Type**: Untrusted filesystem paths from mutable backup data **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 if count > 0: self.backup_file.unlink(missing_ok=True) print(f"已撤销 {count} 个音乐文件的操作") return True else: print("没有需要撤销的音乐文件") return False ``` ### Technical Analysis The undo operation treats every key and value loaded from `.music-tagger-backup.json` as a trusted filesystem path. It does not validate the JSON schema, authenticate the backup, verify file ownership, reject symbolic links, or ensure that canonicalized paths remain within the intended input and output directories. After reversing the attacker-controlled mappings, the code uses one supplied path as the source of `copy2()` and another as its destination. It then unconditionally removes the source with `unlink()` after a successful copy. Consequently, a crafted backup can direct the application to relocate an arbitrary file that the invoking user can read and delete to any nonexistent path whose parent directory the user can write. This does not grant privileges beyond those of the user running the progra ...[truncated 1641 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Define and enforce a strict JSON schema requiring a dictionary of string paths with no unexpected fields or value types. 2. Resolve every path with `Path.resolve()` before use. 3. Require organized-file sources to remain beneath the configured output directory and restoration destinations to remain beneath the original input directory. 4. Reject absolute paths when relative paths are sufficient, as well as paths containing traversal components. 5. Reject symbolic links and verify file types with `lstat()` immediately before copying or deleting. 6. Store only normalized relative paths in the backup rather than unrestricted absolute paths. 7. Protect the backup with restrictive permissions and an integrity mechanism, such as an authenticated digest stored in a trusted location. 8. Before deleting a source, verify that it matches an operation created by the current application and that the copy completed successfully. 9. Present every resolved source and destination for confirmation when restoring files. 10. Avoid using mutable metadata as the sole authorization for destructive filesystem operations. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
music_tagger.py:30
Finding
Backup Creation Follows Symbolic Links and Can Truncate Unintended Files<![CDATA[ ## Vulnerability Details **File Location**: `music_tagger.py:30-34` **Vulnerability Type**: Symbolic-link file overwrite **Risk Level**: Medium ### Vulnerable Code ```python def save_backup(self, mappings): self.output_dir.mkdir(parents=True, exist_ok=True) with open(self.backup_file, 'w', encoding='utf-8') as f: json.dump(mappings, f, indent=2, ensure_ascii=False) ``` ### Technical Analysis The backup is opened in write mode at a predictable filename, `.music-tagger-backup.json`. Standard `open(..., 'w')` follows an existing symbolic link and truncates its target before writing the JSON data. The code does not inspect the path with `lstat()`, reject symbolic links, use exclusive creation, or verify that the opened file is still the expected regular file. If an attacker can prepare content in the selected output directory before the victim runs the organize command, the attacker can replace the expected backup file with a symbolic link to another victim-writable file. ### Attack Path 1. The attacker predicts or controls the output directory used by the victim. 2. The attacker creates `.music-tagger-backup.json` as a symbolic link to a victim-owned target file. 3. The victim runs the non-preview `organize` command and confirms the operation. 4. `save_backup()` follows the symbolic link when opening the backup in write mode. 5. The linked target is truncated and replaced with JSON mapping data under the victim's privileges. ### Impact Assessment Exploitation can corrupt or destroy the contents of any file that the invoking user can write and that can be named as the symbolic-link target. Likely effects include: - Loss of user documents or configuration. - Corruption of application state. - Denial of service for applications relying on the overwritten file. - Replacement of writable structured files with attacker-influenced JSON path data. The operation remains limited by the effective filesystem permissions of the victim proce ...[truncated 7 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Refuse to operate if the backup path already exists as a symbolic link or non-regular file. 2. Inspect the path using `os.lstat()` rather than methods that follow links. 3. Create the backup with no-follow and exclusive-creation semantics, such as `os.open()` with `O_NOFOLLOW`, `O_CREAT`, and appropriate replacement controls. 4. Write to a securely created temporary file in the same trusted directory, flush and synchronize it, and atomically replace a verified regular backup file. 5. Ensure the output directory is owned by the invoking user and is not writable by untrusted users. 6. Set restrictive file permissions, such as `0600`, on backup data. 7. Revalidate the opened file descriptor with `fstat()` to mitigate path replacement races. ]]>

T08 · Insecure Dependencies

Note
Location
README.md:23
Finding
Documentation Instructs Installation of an Unpinned Third-Party Dependency<![CDATA[ ## Vulnerability Details **File Location**: `README.md:23-29`, `SKILL.md:23-27` **Vulnerability Type**: Unpinned third-party dependency **Risk Level**: Low ### Vulnerable Code From `README.md`: ```bash # 克隆或下载项目 git clone <repo-url> cd music-tagger # 安装依赖(需要实际标签编辑功能时) pip install mutagen ``` The same unpinned installation instruction appears in `SKILL.md`: ```bash git clone <repo-url> cd music-tagger pip install mutagen ``` ### Technical Analysis The documentation directs users to install `mutagen` without a version constraint, lockfile, or package hash. As a result, installation resolves whichever package release is current at execution time rather than a version reviewed with this project. Python package installation can execute package-controlled build hooks. If a future release or its distribution channel is compromised, users following these instructions may execute unexpected code during installation. Unpinned installation also prevents reproducible dependency review. The current implementation does not import or use `mutagen`; `read_tags()` and `write_tags()` only simulate metadata operations. Therefore, the documented dependency currently adds supply-chain exposure without supporting an implemented code path. ### Attack Path 1. A user follows the project installation documentation. 2. `pip` resolves the latest available `mutagen` release from the configured package index. 3. A compromised, malicious, or unexpectedly changed release is downloaded. 4. Package-controlled installation hooks execute with the user's privileges, or incompatible code is installed into the environment. 5. The affected dependency can access resources available to the installation process. This finding does not claim that the legitimate `mutagen` package is malicious; the risk results from consuming an unpinned future artifact without integrity verification. ### Impact Assessment If the resolved package or distribution channel is compromised, code may exec ...[truncated 425 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the installation instruction until `mutagen` is actually used by the implementation. 2. When introduced, pin a reviewed version or tightly controlled compatible range. 3. Maintain dependencies in a lockfile generated through a controlled review process. 4. Use hashes and install with a command such as: ```bash pip install --require-hashes -r requirements.txt ``` 5. Review dependency updates before changing the lockfile. 6. Use isolated virtual environments and avoid installing packages with elevated privileges. 7. Keep `README.md` and `SKILL.md` synchronized so both provide the same hardened installation procedure. ]]>
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 (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The documented behavior claims real metadata reading, editing, organization, preview, and undo, but the implementation is reported to fabricate placeholder metadata and simulate writes instead of performing the advertised actions. This mismatch can mislead users and downstream agents into trusting outputs, making incorrect file-management decisions or assuming changes and backups occurred when they did not.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The entire skill description and usage guidance are presented only in Chinese, with no indication that users may choose another language or that the skill is intentionally limited to a Chinese-speaking context. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The README states '工具默认使用模拟编辑(当前版本)' and refers to actual tag editing as a future capability, but elsewhere documents edit, batch edit, organize, backup, and undo as current operational commands. This is an active contradiction in the skill's own documentation about whether modifications are real or only simulated.

Lp3

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding
The skill advertises file-reading and file-writing behavior but does not declare any explicit tool scope or permissions boundaries. For a tool that can edit and reorganize files, this increases the risk of unintended broad filesystem access, especially if an agent grants default or excessive file capabilities.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The manifest description and title are written entirely in Chinese, and the document provides no indication that other languages are supported or that Chinese is required for a region-specific purpose. This creates a natural-language locale constraint without user opt-in, which matches the language policy violation criteria.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The manifest describes a batch music tagging tool that supports reading and editing metadata such as title, artist, album, and genre. However, the core tag operations are mocked: metadata reads are fabricated and writes have no effect, so the advertised tagging capability is not actually implemented.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The docstrings say '读取音乐文件标签' and '写入音乐文件标签', which implies real metadata operations. In reality, read_tags returns hardcoded placeholder values based on the filename, and write_tags only prints simulated actions and returns True without changing the file.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The undo path deletes files with new_path.unlink() after copying them back, but it does so without an explicit confirmation prompt or safety checks on the destination path. If the backup mapping is stale, tampered with, or points to unexpected files, undo can remove user data unexpectedly, making this a real destructive-file-operation risk.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
The file’s title and all user-facing CLI/help strings are written only in Chinese, which imposes a specific language/locale choice without offering the user an alternative. The policy allows fixed locale behavior when it is explicitly justified or optional, but this file does not document such a constraint.

Static analysis

No suspicious patterns detected.