Back to skill

Security audit

File Organizer Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed local file organizer, but its undo mode can move arbitrary files based on an untrusted history JSON file.

Install only if you are comfortable with a local script that moves files. Use dry-run first, run it only on directories you explicitly choose, avoid recursive mode on broad folders, and do not use --undo with a history file you did not create and inspect.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/organize.py:116
Finding

Untrusted Undo History Allows Arbitrary File Moves and Log Deletion

Content
View full analysis

Vulnerability Details

File Location: scripts/organize.py, lines 116–135
Vulnerability Type: Unvalidated path usage from an untrusted history file
Risk Level: Medium

python
def undo(self, log_file):
    if not os.path.exists(log_file):
        logger.error("Log file not found.")
        return

    with open(log_file, 'r') as f:
        history = json.load(f)
    
    logger.info(f"Undoing {len(history)} operations...")
    for item in reversed(history):
        src = item['src']
        dst = item['dst']
        try:
            if os.path.exists(dst):
                shutil.move(dst, src)
                logger.info(f"Restored: {os.path.basename(dst)} -> {os.path.dirname(src)}")
        except Exception as e:
            logger.error(f"Failed to restore {dst}: {e}")
    
    os.remove(log_file)
    logger.info("Undo complete.")

Technical Analysis

The --undo option accepts an arbitrary JSON file and directly uses its attacker-controlled src and dst values as arguments to shutil.move(). The implementation does not:

  • Validate the structure or types of history entries.
  • Canonicalize paths before using them.
  • Require paths to remain beneath the directory that was organized.
  • Verify that the history was generated by this application.
  • Reject symbolic links or path traversal.
  • Check for destination conflicts before restoration.
  • Preserve the history file when one or more operations fail.

Consequently, a crafted history entry can select any existing file accessible to the process as dst and any writable path as src. shutil.move(dst, src) will then relocate that file. Depending on platform and destination semantics, an existing destination may also be replaced or the selected file may be moved into an attacker-selected directory.

The history file is unconditionally deleted after processing, including when restoration operations fail. This can re ...[truncated 1593 chars]

Remediation
View remediation

Remediation Suggestions

  1. Validate the loaded JSON against a strict schema:
    • Require the root value to be a list.
    • Require each entry to contain only string-valued src and dst fields.
    • Reject malformed, missing, or unexpected fields.
  2. Store the organization root and a format version in the history file.
  3. Resolve every path with os.path.realpath() and verify, using os.path.commonpath(), that both source and destination remain under the recorded organization root.
  4. Reject entries containing paths outside that root, including paths that escape through symbolic links.
  5. Consider refusing history files not generated by the application. Where authenticity is required, protect history files with restrictive permissions or a keyed integrity check.
  6. Before moving a file, verify that the current file state matches the recorded operation and refuse destination conflicts rather than implicitly replacing or nesting files.
  7. Use a two-phase undo process: validate every entry before performing any move, then execute only if the complete history is valid.
  8. Delete or archive the history file only after all operations succeed. Preserve it and return a nonzero exit status when an undo is incomplete.
  9. Add a dry-run option for undo so users can review all resolved source and destination paths before filesystem changes occur.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • 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)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill invokes a local Python script that reads directories, moves files, and writes an audit/history file, yet the manifest declares no explicit tool scope such as file read/write permissions. This creates an under-declared capability boundary: a user or platform may trust the skill description without realizing it can modify the filesystem, increasing the risk of unintended file movement, overwrites via logic bugs, or misuse in broader directories.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The undo feature trusts an arbitrary JSON history file path and blindly replays its src/dst entries with shutil.move(), without validating that the log was produced by this tool or that paths stay within the intended root directory. An attacker who can supply or modify the history file can cause files to be moved to attacker-chosen locations, which can disrupt application state, overwrite expected files via relocation, or abuse a trusted operator into performing unauthorized file operations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

Line L133 removes the user-supplied history file as part of the undo operation. Although the script logs progress, it does not clearly warn beforehand that undo will also delete the log file, which is an irreversible file operation that may matter to users who expect to retain the audit trail.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.