Back to skill

Security audit

File Batch Processor

Security checks for vulnerabilities and agentic risk

Overview

This is a local batch file tool, but it can overwrite, move, or corrupt many user files without enough safeguards.

Review before installing. Use this only on copied folders or backed-up data, run --dry-run first, avoid using it on important originals, and do not rely on it to preserve GIF/BMP formats or existing PDFs. Prefer waiting for a version that defaults to safe output folders, pins dependencies, validates rename paths, checks collisions, and implements real backups or rollback.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/batch_rename.py:46
Finding
Path Traversal and File Overwrite Through Unvalidated Rename Parameters<![CDATA[ ## Vulnerability Details **File Location**: `scripts/batch_rename.py`, lines 46-69 **Vulnerability Type**: Unvalidated destination path and unsafe file replacement **Risk Level**: High ### Vulnerable Code ```python if mode == 'sequence': new_name = f"{prefix}{str(start_num + i).zfill(3)}{suffix}{ext}" elif mode == 'date': date_str = datetime.now().strftime(date_format) new_name = f"{prefix}{date_str}{suffix}{ext}" elif mode == 'prefix': new_name = f"{prefix}{name}{suffix}{ext}" elif mode == 'suffix': new_name = f"{name}{suffix}{ext}" elif mode == 'replace': new_name = filename.replace(replace_old, replace_new) else: print(f"Unknown renaming mode: {mode}") continue new_path = os.path.join(folder_path, new_name) # Check for duplicate names if old_path == new_path: continue if dry_run: print(f"Preview: {filename} → {new_name}") else: try: os.rename(old_path, new_path) ``` ### Technical Analysis The `prefix`, `suffix`, `replace_old`, and `replace_new` command-line values are incorporated into `new_name` without rejecting absolute paths, parent-directory components, or platform-specific directory separators. Passing a value containing `../`, `..\`, or an absolute path can cause `os.path.join()` to produce a destination outside the selected directory. The comment stating that duplicate names are checked is inaccurate. The code only detects a no-op rename where the source and destination strings are identical. It does not detect: - Multiple source files mapping to the same destination. - A destination that already exists. - A destination that resolves outside `folder_path`. - Case-insensitive collisions on Windows. - Symlink or junction traversal. On platforms and filesystems where `os.rename()` replaces an existing ...[truncated 1223 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Reject absolute paths, parent-directory components, null bytes, and both Windows and POSIX path separators in all filename parameters. 2. Resolve the source directory and every proposed destination with `Path.resolve()`, then verify that the destination remains a direct child of the source directory. 3. Precompute the complete rename plan before changing any files. 4. Reject duplicate destinations, case-folded collisions, and destinations that already exist. 5. Use a two-phase rename through uniquely generated temporary names to prevent source-to-destination cycles. 6. Refuse replacement by default. If replacement is required, expose an explicit `--overwrite` option and request confirmation. 7. Record an operation journal or provide a rollback manifest. 8. Avoid running the utility with administrative privileges. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/convert_to_pdf.py:75
Finding
Predictable Shared Temporary File Enables File Clobbering and Race Conditions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/convert_to_pdf.py`, lines 75-79 **Vulnerability Type**: Unsafe predictable temporary file **Risk Level**: High ### Vulnerable Code ```python # Resize image and save to PDF img.save('temp_image.jpg', quality=95) pdf.image('temp_image.jpg', x=(210-new_width)/2, y=(297-new_height)/2, w=new_width, h=new_height) pdf.output(pdf_path) os.remove('temp_image.jpg') ``` ### Technical Analysis Every image conversion writes to the fixed relative path `temp_image.jpg` in the process's current working directory. The file is neither created exclusively nor checked for pre-existence or symlinks. Consequently: - An existing file with that name is overwritten and then deleted. - A local attacker may pre-create a symbolic link or comparable filesystem redirection at that path. - Concurrent converter instances use the same file and can corrupt one another's output. - An exception between creation and deletion can leave temporary image data behind. - The location is based on the current working directory rather than a protected temporary directory. ### Attack Path 1. A local attacker identifies a writable working directory from which the converter will run. 2. The attacker creates `temp_image.jpg` as a symbolic link to a file writable by the converter's account, or places a valuable regular file at that path. 3. The victim runs image-to-PDF conversion. 4. `img.save()` follows the fixed path and overwrites its target with JPEG data. 5. The converter later removes `temp_image.jpg`, or an exception leaves the temporary data exposed. For a race-condition attack, two converter processes can be started simultaneously. Each process writes and reads the same temporary filename, producing incorrect PDFs or failed conversions. ### Impact Assessment The attacker can clob ...[truncated 344 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the fixed filename with `tempfile.NamedTemporaryFile` or `tempfile.TemporaryDirectory`. 2. Use exclusive file creation and a system-managed temporary directory with restrictive permissions. 3. Put cleanup in a `finally` block or use context managers so exceptions cannot leave temporary files behind. 4. Ensure temporary paths are not symlinks before use and do not reuse attacker-controlled paths. 5. Prefer an in-memory `io.BytesIO` buffer if the PDF library supports it. 6. Generate a unique temporary file per source image and per process. 7. Avoid executing the converter with elevated privileges. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/image_compress.py:41
Finding
In-Place Image Processing Can Irreversibly Corrupt BMP and GIF Files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/image_compress.py`, lines 41-65 **Vulnerability Type**: Destructive in-place conversion and format-extension mismatch **Risk Level**: Medium ### Vulnerable Code ```python # Create backup filename backup_name = f"{name}_backup{ext}" backup_path = os.path.join(folder_path, backup_name) try: # Open image with Image.open(old_path) as img: # Record original info original_size = os.path.getsize(old_path) original_width, original_height = img.size # Adjust size if resize_ratio < 1.0: new_width = int(original_width * resize_ratio) new_height = int(original_height * resize_ratio) img = img.resize((new_width, new_height), Image.Resampling.LANCZOS) # Save compressed image if dry_run: print(f"Preview: {filename} ({original_width}x{original_height}) → Quality{quality}%, Size{resize_ratio*100}%") else: # Save as JPEG (keep original format) if ext.lower() in ['.jpg', '.jpeg']: img.save(old_path, 'JPEG', quality=quality, optimize=True, progressive=True) else: img.save(old_path, 'PNG', optimize=True, compress_level=6) ``` ### Technical Analysis Although the script computes `backup_name` and `backup_path`, it never creates a backup. It writes directly over the source file. All supported non-JPEG inputs—including PNG, BMP, and GIF—are encoded as PNG while retaining their original extension. A `.bmp` file can therefore contain PNG bytes, and a `.gif` file can be replaced with PNG data. Animated GIF processing generally operates on the current frame, causing animation frames and timing information to be lost. The write is performed directly again ...[truncated 1005 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Implement the advertised backup behavior before changing an original file. 2. Write compressed output to a separate output directory by default. 3. Preserve the source format when that format is supported. 4. If conversion to PNG is intentional, change the destination extension to `.png` and require explicit user confirmation. 5. Handle animated GIFs frame by frame while preserving duration, disposal, loop, and transparency information, or reject them clearly. 6. Write to a uniquely named temporary file, validate the result, and atomically replace the original only after success. 7. Detect destination collisions and refuse replacement unless an explicit overwrite option is supplied. 8. Add tests that verify file signatures, extensions, animation preservation, and interruption safety. ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:30
Finding
Unpinned Third-Party Dependencies Create Supply-Chain and Reproducibility Risk<![CDATA[ ## Vulnerability Details **File Location**: `README.md`, line 30 **Vulnerability Type**: Unpinned dependency installation **Risk Level**: Medium ### Vulnerable Code ```bash pip install Pillow PyPDF2 fpdf ``` ### Technical Analysis The installation command does not pin package versions, provide integrity hashes, use a lockfile, or state which package index is trusted. The effective code installed by users can therefore change over time and can also depend on their local pip index configuration. If a configured package index is compromised or untrusted, package resolution may install attacker-controlled content. Even without malicious interference, mutable dependency versions make builds non-reproducible and can introduce newly published vulnerabilities or incompatible behavior. `PyPDF2` is imported by `scripts/convert_to_pdf.py` but is not used, unnecessarily increasing the package and transitive dependency surface. ### Attack Path 1. A user follows the documented installation command. 2. Pip resolves the latest matching releases from the user's configured indexes. 3. A compromised index, account, package release, or unsafe index configuration supplies a malicious or vulnerable dependency. 4. Package installation or later import executes dependency-controlled code under the user's account. 5. The dependency receives the same filesystem and process privileges as the Skill. No evidence in the audited repository establishes that the named packages are currently malicious. The vulnerability is the absence of dependency pinning, integrity verification, and provenance controls. ### Impact Assessment A compromised dependency can execute arbitrary Python code with the privileges of the user installing or running the Skill. This could affect files, environment variables, credentials accessible to that account, and network resources. The repository itself contains no confirmed malicious dependency payload, so exploitation requires compromise or substi ...[truncated 40 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the unused `PyPDF2` dependency and corresponding import. 2. Provide a reviewed requirements or lock file with exact versions. 3. Include cryptographic hashes and install with `pip install --require-hashes`. 4. Document and enforce a trusted HTTPS package index. 5. Review dependency licenses, advisories, maintainership, and release changes before updating pins. 6. Use automated dependency scanning and controlled update pull requests. 7. Install dependencies in an isolated virtual environment under a non-privileged account. 8. Publish tested Python and dependency version combinations. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/convert_to_pdf.py:47
Finding
PDF Conversion Silently Replaces Existing Output Files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/convert_to_pdf.py`, lines 47-94 **Vulnerability Type**: Unchecked output collision and destructive overwrite **Risk Level**: Medium ### Vulnerable Code ```python old_path = os.path.join(folder_path, filename) name, ext = os.path.splitext(filename) # Generate PDF filename pdf_filename = f"{name}.pdf" pdf_path = os.path.join(output_folder, pdf_filename) try: if dry_run: print(f"Preview: {filename} → {pdf_filename}") else: if ext.lower() in image_extensions: # Image to PDF with Image.open(old_path) as img: # Create PDF pdf = FPDF() pdf.add_page() # Calculate appropriate size width, height = img.size max_width = 200 # mm max_height = 280 # mm if width > height: new_width = max_width new_height = height * (max_width / width) else: new_height = max_height new_width = width * (max_height / height) # Resize image and save to PDF img.save('temp_image.jpg', quality=95) pdf.image('temp_image.jpg', x=(210-new_width)/2, y=(297-new_height)/2, w=new_width, h=new_height) pdf.output(pdf_path) os.remove('temp_image.jpg') elif ext.lower() in text_extensions: # Text to PDF pdf = FPDF() pdf.add_page() pdf.set_font("Arial", size=12) # Read text file with open(old_ ...[truncated 1655 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Check whether each destination exists before conversion. 2. Refuse replacement by default and require an explicit `--overwrite` option. 3. Detect all output collisions before starting the batch, including multiple inputs mapping to one PDF. 4. Offer deterministic collision-safe names or preserve source extensions in generated names. 5. Write each PDF to a unique temporary file in the output directory, validate it, and atomically move it into place. 6. Display the complete conversion plan and request confirmation when any existing destination would be affected. 7. Return a failure status when a collision or conversion error occurs instead of reporting overall success unconditionally. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The finding specifically notes safety-signaling language such as 'safe' and mentions backup behavior that may not actually occur while originals are overwritten. False assurances around backup and safety are particularly dangerous for batch file processors because they can directly cause irreversible user data loss.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The finding specifically notes safety-signaling language such as 'safe' and mentions backup behavior that may not actually occur while originals are overwritten. False assurances around backup and safety are particularly dangerous for batch file processors because they can directly cause irreversible user data loss.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The finding specifically notes safety-signaling language such as 'safe' and mentions backup behavior that may not actually occur while originals are overwritten. False assurances around backup and safety are particularly dangerous for batch file processors because they can directly cause irreversible user data loss.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The finding specifically notes safety-signaling language such as 'safe' and mentions backup behavior that may not actually occur while originals are overwritten. False assurances around backup and safety are particularly dangerous for batch file processors because they can directly cause irreversible user data loss.

Ssd 3

Medium
Confidence
92% confidence
Finding
The checklist exposes what appears to be a personal account identifier in plain text: 'ClawHub account login (lx19840614)'. Even if it is only a username and not a password, publishing account identifiers helps attackers enumerate valid accounts, target credential-stuffing or phishing attacks, and associate a real individual with the asset. In a commercial skill-release context, this makes the account and related dashboard actions more attractive targets.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill advertises file-manipulation behavior but does not declare an explicit tool scope such as permissions or allowed-tools. In a batch-processing context, undeclared read/write capability increases the chance of unintended or overly broad filesystem access, making user consent and policy enforcement weaker.

Vague Triggers

Medium
Confidence
86% confidence
Finding
An overly broad description can cause the skill to be invoked for generic file-related requests beyond its safe or intended scope. In a filesystem-modifying tool, over-triggering increases the chance that users run batch operations in inappropriate contexts or on unintended directories.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill performs or advertises batch rename, compression, conversion, and organization workflows, all of which can modify or overwrite large numbers of files, yet the description lacks a strong upfront destructive-operation warning. In batch contexts, insufficient warning materially raises the risk of accidental data loss at scale.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The tool advertises support for GIF and BMP and comments imply original formats are preserved, but the implementation writes all non-JPEG inputs using PNG encoding back to the original path. This can corrupt files or produce mislabeled content (for example, a .gif or .bmp file containing PNG data), causing data loss, application failures, and unexpected behavior during batch processing.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script overwrites original images in place during batch processing without a real backup or a clear destructive-operation warning. In this skill context, marketed as a one-click newbie-friendly file tool, that makes accidental irreversible data loss more likely because users may process entire folders expecting safe compression rather than permanent modification.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
This markdown file uses English throughout for operational instructions, checklists, and user-facing planning content, but it does not indicate that English is optional or required for a justified region-specific reason. Under the language/locale policy check, forcing a single language without opt-in can be a natural-language policy violation.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The line states that for TXT/MD conversion, 'English works best,' which expresses a language preference in the skill description. Under the policy, forcing or preferring a specific language without explicit user choice can be a natural-language policy issue, especially since no opt-in or alternative language support choice is offered here.

Static analysis

No suspicious patterns detected.