Back to skill

Security audit

Batch File Renamer

Security checks for vulnerabilities and agentic risk

Overview

This skill is a normal batch file-renaming guide, but its examples can move or overwrite files in ways users may not expect.

Review this skill carefully before installing or using its examples. It does not appear deceptive or malicious, but the provided code can rename, move, or overwrite user files if patterns or generated names are wrong. Use only on test copies or backed-up folders, and add checks for path boundaries, collisions, and file type before running any actual rename operation.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:29
Finding

Unrestricted Rename Destination Allows Path Traversal

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 29-36
Vulnerability Type: Unrestricted destination path / path traversal
Risk Level: High

python
renamed = []
for filename in os.listdir(directory):
    new_name = re.sub(pattern, replacement, filename)
    if new_name != filename:
        old_path = os.path.join(directory, filename)
        new_path = os.path.join(directory, new_name)
        os.rename(old_path, new_path)
        renamed.append((filename, new_name))

Technical Analysis

The generated new_name is derived from the caller-controlled regular-expression replacement and is passed to os.path.join() without validation. A replacement can contain parent-directory components such as ../, path separators, or an absolute path.

If new_name is absolute, os.path.join(directory, new_name) discards the intended base directory. If it contains parent-directory components, path resolution can escape the selected directory. The same underlying weakness is also present in the documented safe_rename() implementation at lines 123-150. Its dry-run option does not make an actual run safe because destination paths remain unrestricted when dry_run=False.

Attack Path

  1. An attacker influences the replacement value supplied to batch_rename() or safe_rename().
  2. The attacker provides a replacement containing an escape path, such as ../target/\1, or an absolute destination path.
  3. re.sub() produces a destination name containing that path.
  4. os.path.join() constructs a destination outside the requested directory.
  5. When execution reaches os.rename(), a source entry is moved to an unintended writable location.
  6. If a destination already exists and the operating system permits replacement, that destination may be overwritten.

Impact Assessment

The operation runs with the privileges of the Python process. An attacker can move affected files to any destinat ...[truncated 339 chars]

Remediation
View remediation

Remediation Suggestions

  • Accept only a basename as the generated destination name.
  • Reject absolute paths, .. components, directory separators, NUL characters, and platform-specific alternate separators.
  • Resolve the base and destination paths with pathlib.Path.resolve() and verify that the destination remains a direct child of the resolved base directory.
  • Perform the boundary check immediately before renaming to reduce time-of-check/time-of-use exposure.
  • Do not rely on a dry run as a security control; repeat all validation during the actual operation.
  • Require explicit authorization before replacing any existing destination.
  • Consider using directory file descriptors and relative rename operations on platforms that support them to constrain filesystem operations more robustly.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:51
Finding

Unchecked Rename Collisions Can Overwrite Files and Corrupt Batch Operations

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 51-64
Vulnerability Type: Unsafe file overwrite and rename collision
Risk Level: High

python
files = sorted([f for f in os.listdir(directory) 
               if extension is None or f.endswith(extension)])

renamed = []
for i, filename in enumerate(files, 1):
    old_path = os.path.join(directory, filename)
    ext = os.path.splitext(filename)[1]
    new_name = f"{prefix}{str(i).zfill(digits)}{ext}"
    new_path = os.path.join(directory, new_name)
    os.rename(old_path, new_path)
    renamed.append((filename, new_name))

return renamed

Technical Analysis

The implementation renames entries immediately without first validating the complete mapping of sources to destinations. It does not check whether:

  • Multiple sources generate the same destination.
  • A generated destination already exists.
  • A destination is another source that has not yet been processed.
  • A rename cycle exists.
  • A previous operation left the directory in a partially renamed state.

The basic, timestamp, and safe_rename() examples likewise call os.rename() without collision protection. On operating systems where os.rename() replaces an existing file, this may silently destroy destination data. On platforms that reject a collision, the batch may stop after some files have already been renamed, leaving an inconsistent partial result.

Sequential numbering is particularly vulnerable to ordering conflicts. For example, an existing Project_001.pdf may be selected as either a source or destination while another source is being assigned that same name.

Attack Path

  1. An attacker or another user places a file whose name matches a predictable generated destination in the target directory.
  2. The victim runs sequential, regex-based, or timestamp-based renaming.
  3. The implementation does not identify the existing destination or a source-to-dest ...[truncated 699 chars]
Remediation
View remediation

Remediation Suggestions

  • Construct the entire source-to-destination plan before modifying the filesystem.
  • Reject duplicate destinations and destinations that already exist unless the user has explicitly authorized replacement.
  • Detect rename cycles and cases where a destination is an unprocessed source.
  • Use a two-phase algorithm: first rename each source to a unique temporary name in the same directory, then rename each temporary entry to its final validated destination.
  • Generate temporary names with a cryptographically strong random component and create them exclusively to prevent collisions.
  • Revalidate destination existence immediately before each operation.
  • Implement rollback or recovery reporting if any operation fails.
  • Show the validated plan in preview mode and require confirmation before executing destructive changes.
  • Prefer APIs or flags that provide no-replace semantics where the operating system supports them.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:29
Finding

Directory Entries Are Renamed Without File-Type Validation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 29-36
Vulnerability Type: Improper filesystem object validation
Risk Level: Medium

python
renamed = []
for filename in os.listdir(directory):
    new_name = re.sub(pattern, replacement, filename)
    if new_name != filename:
        old_path = os.path.join(directory, filename)
        new_path = os.path.join(directory, new_name)
        os.rename(old_path, new_path)
        renamed.append((filename, new_name))

Technical Analysis

os.listdir() returns names for multiple kinds of directory entries, including regular files, subdirectories, symbolic links, and other filesystem objects. The implementation does not call os.path.isfile(), inspect entries with os.scandir(), or otherwise enforce that only regular files are processed.

Consequently, broad regular-expression patterns can rename subdirectories or symbolic links even though the skill is presented as a file-renaming utility. Extension filtering in the sequential example is only a name check and does not establish the object type.

Attack Path

  1. The selected directory contains subdirectories, symbolic links, or other non-regular entries.
  2. The user supplies a broad pattern that also matches those entry names.
  3. The loop processes every matching name returned by os.listdir().
  4. os.rename() renames the non-file entry along with regular files.
  5. Applications, scripts, or users relying on the original directory structure can no longer find the renamed resources.

Impact Assessment

The issue can alter directory structure and rename symbolic links or other entries within locations writable by the executing process. It may break projects, media libraries, automation, or application paths. It does not by itself provide elevated privileges, and os.rename() renames a symbolic link itself rather than the link target, but the resulting structural disruption can exten ...[truncated 45 chars]

Remediation
View remediation

Remediation Suggestions

  • Use os.scandir() and process only entries whose type is explicitly permitted.
  • For file-only behavior, require entry.is_file(follow_symlinks=False).
  • Skip symbolic links, directories, sockets, devices, and other special entries by default.
  • If directory renaming is desired, expose it as a separate opt-in mode with a clear preview and confirmation step.
  • Report skipped entries and their types so users can verify the operation's scope.
  • Recheck object identity and type immediately before renaming when operating in directories that may be modified concurrently.
Vulnerability Patterns
  • 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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep

Static analysis

No suspicious patterns detected.