Back to skill

Security audit

rename-fill

Security checks for vulnerabilities and agentic risk

Overview

The skill is a normal batch file renamer, but its helper script can move files outside the selected folder if given a path-like prefix.

Review this skill before installing or using it on important directories. It should reject prefixes containing slashes, backslashes, drive syntax, NUL, or .., and it should verify every resolved destination remains inside the selected folder. Until fixed, only use simple prefixes like letters, numbers, underscores, or hyphens, and avoid running it on folders without backups.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/rename-files.js:52
Finding

Unvalidated Prefix Allows Files to Be Moved Outside the Selected Directory

Content
View full analysis

Vulnerability Details

File Location: scripts/rename-files.js, lines 18, 52-55, and 82
Vulnerability Type: Path traversal in a filesystem destination
Risk Level: High

Vulnerable Code

js
const prefix = args[0];
js
const newName = prefix + baseName + extension;

const oldPath = path.join(dirPath, oldName);
const newPath = path.join(dirPath, newName);
js
fs.renameSync(op.oldPath, op.newPath);

Technical Analysis

The command-line prefix is incorporated directly into newName without validating that it is a filename component. The resulting value is passed to path.join and ultimately used as the destination of fs.renameSync.

A prefix containing parent-directory components, such as ../moved_, produces a normalized destination outside the selected directory. For example, processing /chosen/dir/file.txt with that prefix constructs a destination equivalent to /chosen/moved_file.txt. The script therefore performs a file move rather than an in-directory rename.

This contradicts the skill's declared behavior of adding a prefix to files in the selected directory. Although SKILL.md states that the prefix should be sanitized if necessary, no such validation is implemented.

Attack Path

  1. An attacker or mistaken user supplies a prefix containing traversal components, such as ../moved_.
  2. The Agent invokes the script with that prefix and an otherwise valid target directory.
  3. The script concatenates the prefix with every file's base name.
  4. path.join normalizes the resulting .. component.
  5. fs.renameSync moves each affected file into the parent directory, provided that the process has the required filesystem permissions.
  6. Additional traversal components can target other reachable directories where the destination path exists and is writable.

Impact Assessment

The vulnerability allows files selected by the script to be relocated outsid ...[truncated 516 chars]

Remediation
View remediation

Remediation Suggestions

  • Treat the prefix strictly as a filename prefix rather than a path.

  • Reject prefixes containing /, \, NUL, .., absolute-path syntax, drive prefixes, or platform-specific path separators.

  • Prefer a conservative allowlist, such as letters, digits, spaces, underscores, and hyphens.

  • Resolve the selected directory and destination, then verify that the destination's parent is exactly the selected directory:

    js
    const root = path.resolve(dirPath);
    
    if (
      prefix.length === 0 ||
      prefix.includes('\0') ||
      prefix.includes('/') ||
      prefix.includes('\\') ||
      prefix === '..' ||
      prefix.includes('../') ||
      prefix.includes('..\\')
    ) {
      throw new Error('Prefix must be a plain filename prefix');
    }
    
    const newName = prefix + baseName + extension;
    const newPath = path.resolve(root, newName);
    
    if (path.dirname(newPath) !== root) {
      throw new Error('Destination escapes the selected directory');
    }
    
  • Perform this containment check immediately before every rename rather than relying only on Agent-side input validation.

  • Include the fully resolved source and destination paths in the preview so that users can verify the actual filesystem effects.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/rename-files.js:58
Finding

Time-of-Check to Time-of-Use Race Can Replace a Concurrently Created Destination

Content
View full analysis

Vulnerability Details

File Location: scripts/rename-files.js, lines 58-63 and 80-83
Vulnerability Type: Filesystem TOCTOU race condition
Risk Level: Medium

Vulnerable Code

js
// Check if target already exists
if (fs.existsSync(newPath)) {
  console.error(`Error: Cannot rename "${oldName}" -> "${newName}" (file already exists)`);
  continue;
}

operations.push({ oldPath, newPath, oldName, newName });
js
for (const op of operations) {
  try {
    fs.renameSync(op.oldPath, op.newPath);

Technical Analysis

The script checks destination existence while preparing the operations list, but performs the actual renames later in a separate loop. The existence check and filesystem mutation are not atomic.

A concurrent process can create or replace newPath after fs.existsSync reports that it does not exist but before fs.renameSync executes. On platforms and filesystems where rename operations replace an existing destination, the script can overwrite the concurrently created file despite its documented promise to skip existing destinations.

Rechecking with another existsSync call would narrow but not eliminate the race because another process could still modify the path between the repeated check and the rename.

Attack Path

  1. The script enumerates files and calculates their destination names.
  2. fs.existsSync(newPath) reports that a destination does not exist.
  3. The operation is added to the pending operations array.
  4. Before the rename loop reaches that operation, a concurrent local process creates a file at newPath.
  5. fs.renameSync executes against the same destination.
  6. Where the operating system permits replacement during rename, the newly created destination is overwritten.

Exploitation requires the attacker or concurrent process to have write access to the destination directory and sufficient timing or repeated attempts to win the race.

...[truncated 520 chars]

Remediation
View remediation

Remediation Suggestions

  • Do not use existsSync as the security mechanism for preventing replacement; existence checks followed by mutation are inherently subject to TOCTOU races.
  • Use an operating-system or filesystem primitive that atomically performs a no-replace rename when available.
  • If Node.js does not expose the required primitive on supported platforms, use a carefully reviewed native implementation or redesign the operation to reserve destinations atomically.
  • Restrict operations to trusted directories that cannot be modified by untrusted concurrent users.
  • Validate the source and destination again immediately before mutation, while recognizing that validation alone cannot fully eliminate the race.
  • Clearly document platform-specific rename behavior and fail closed when atomic no-replace semantics cannot be guaranteed.
  • Add concurrency tests that create destination files between operation planning and execution and verify that existing data is never replaced.
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 (2)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The code largely matches the stated primary purpose: it renames files in a specified directory with a given prefix and prints the planned changes before execution. However, the description explicitly says the skill prompts the user for a prefix and directory path and asks for confirmation before executing. This code only accepts command-line arguments and performs the rename operations directly after printing the list of planned changes. There is no interactive prompt or confirmation step. That is a material behavior mismatch because it removes a stated safety gate before modifying files.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 107)May include surrounding context.

md
The JavaScript script (`scripts/rename-files.js`):

Static analysis

No suspicious patterns detected.