Back to skill

Security audit

Backup Tool

Security checks for vulnerabilities and agentic risk

Overview

This backup skill needs review because it claims protections like encryption and exclusions that are not actually implemented, and its restore path can write outside the chosen folder from a crafted archive.

Do not rely on this skill for sensitive or encrypted backups as published. Treat its archives as plaintext, do not restore archives you do not fully trust, do not depend on --exclude, and avoid unattended broad backups such as /home until the documentation and implementation are corrected.

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
scripts/backup.py:58
Finding
Unsafe Tar Archive Extraction Allows Writes Outside the Restore Destination<![CDATA[ ## Vulnerability Details **File Location**: `scripts/backup.py`, lines 58–78 **Vulnerability Type**: Unsafe archive extraction **Risk Level**: High ### Vulnerable Code ```python def restore_backup(backup_file, destination, verbose=False): """Restore from a backup archive.""" dest_path = Path(destination) backup_path = Path(backup_file) if not backup_path.exists(): print(f"Error: {backup_file} does not exist") return 1 print(f"Restoring from: {backup_file}") print(f"Destination: {dest_path}") try: dest_path.mkdir(parents=True, exist_ok=True) with tarfile.open(backup_path, 'r:*') as tar: tar.extractall(dest_path) print(f"Restore complete: {destination}") return 0 except Exception as e: print(f"Error restoring backup: {e}") return 1 ``` ### Technical Analysis The restore operation passes every archive member directly to `tar.extractall()` without explicitly selecting a safe extraction filter or independently validating member paths and link targets. On Python versions where restrictive filtering is not the default, a malicious tar archive can contain absolute paths, `..` path traversal components, symbolic links, hard links, or special entries. Such members may escape the intended destination and cause files to be created or overwritten elsewhere. Checking that the archive itself exists does not establish that its contents are trustworthy. Creating the destination directory also does not constrain archive members to that directory. ### Attack Path 1. An attacker creates a tar archive containing a member such as `../../.config/application/startup.conf`, an absolute path, or a link that redirects a subsequent extraction outside the destination. 2. The attacker supplies the archive to a user or places it where the user will restore it. 3. The user runs the documented restore operation with `--restore` and `--des ...[truncated 981 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use the safest supported `tarfile` extraction filter explicitly rather than depending on runtime defaults. 2. Before extraction, resolve and validate every archive member path and ensure it remains beneath the resolved destination directory. 3. Reject absolute paths, parent-directory traversal, device entries, FIFOs, and other special file types that are unnecessary for backups. 4. Validate symbolic-link and hard-link targets, or reject links entirely unless they are required. 5. Avoid restoring untrusted archives with elevated privileges. 6. Add regression tests containing absolute paths, `../` traversal, symbolic-link escapes, hard-link escapes, and special entries. 7. Consider extracting into a newly created restricted staging directory and moving validated content to the final destination afterward. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/backup.py:17
Finding
Accepted Exclusion Rules Are Silently Ignored<![CDATA[ ## Vulnerability Details **File Location**: `scripts/backup.py`, lines 17–48 and 115–142 **Vulnerability Type**: Security control accepted but not enforced **Risk Level**: Medium ### Vulnerable Code ```python def create_backup(source, output, compress='gzip', exclude=None, verbose=False): """Create a backup archive.""" source_path = Path(source).resolve() if not source_path.exists(): print(f"Error: {source} does not exist") return 1 # Determine compression mode comp_mode = { 'gzip': 'w:gz', 'bzip2': 'w:bz2', 'xz': 'w:xz', 'none': 'w' }.get(compress, 'w:gz') print(f"Creating backup: {output}") print(f"Source: {source_path}") print(f"Compression: {compress}") try: with tarfile.open(output, comp_mode) as tar: # Add files tar.add(source_path, arcname=source_path.name) ``` ```python parser.add_argument('--exclude', action='append', help='Exclude patterns') ``` ```python return create_backup(args.source, args.output, args.compress, args.exclude, args.verbose) ``` ### Technical Analysis The command-line parser accepts one or more `--exclude` values and passes them into `create_backup()`. The function never uses the `exclude` parameter when adding content to the archive. Instead, `tar.add()` recursively includes the entire source. This creates a dangerous discrepancy between the interface and actual behavior. A successful backup gives no warning that exclusion rules were ignored. Users can therefore reasonably believe sensitive files were omitted when they remain present in the archive. The issue is especially relevant to the documented scheduled-backup example, which backs up the broad `/home` path. An exclusion failure over such a source could expose credentials and private application data. ### Attack Path 1. A user selects a broad source directory containing secrets, private keys, credent ...[truncated 1026 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Implement exclusion processing through a `tar.add()` filter callback or a controlled file traversal routine. 2. Define whether patterns are shell globs, relative paths, or another documented format, and apply them consistently to normalized archive-relative paths. 3. Ensure excluded directories are not recursively traversed. 4. Reject `--exclude` with a clear error until it is implemented; silently ignoring it is unsafe. 5. Print the effective exclusions when verbose mode is enabled. 6. Add automated tests proving that excluded files, nested directories, hidden files, and symbolic links do not appear in generated archives. 7. Update the scheduling example to use a narrowly selected source directory rather than `/home`. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:1
Finding
Documented Encryption and Integrity Protections Are Not Implemented<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 1–64; `scripts/backup.py`, lines 28–48 and 104–117 **Vulnerability Type**: Misrepresented security functionality **Risk Level**: Medium ### Vulnerable Code and Documentation ```markdown --- name: backup-tool description: Backup and restore files with compression and encryption. Use when user needs to backup important files, create scheduled backups, sync folders, encrypt sensitive backups, or restore from backup archives. --- ``` ```markdown Options: --output PATH Output backup file --compress FORMAT Compression: gzip, bzip2, xz (default: gzip) --encrypt Encrypt backup with password --restore PATH Restore from backup --destination DIR Restore destination --incremental Create incremental backup --exclude PATTERN Exclude pattern (can repeat) ``` ```markdown # Encrypted backup python scripts/backup.py ~/Important --output secure-backup.tar.gz --encrypt ``` ```markdown ## Features - Compression: gzip, bzip2, xz - AES-256 encryption - Incremental backups - Exclude patterns - Integrity verification ``` The actual parser does not define the documented encryption or incremental options: ```python parser = argparse.ArgumentParser(description='Backup Tool') parser.add_argument('source', nargs='?', help='Source folder to backup') parser.add_argument('--output', help='Output backup file') parser.add_argument('--compress', default='gzip', choices=['gzip', 'bzip2', 'xz', 'none'], help='Compression format') parser.add_argument('--restore', help='Restore from backup file') parser.add_argument('--destination', help='Restore destination') parser.add_argument('--list', help='List backup contents') parser.add_argument('--exclude', action='append', help='Exclude patterns') parser.add_argument('--verbose', action='store_true') ``` The checksum is only calculated and displayed in truncated form: ```python # Calculate chec ...[truncated 2308 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all encryption, incremental-backup, and integrity-verification claims until those features are implemented and tested. 2. If encryption is required, use a reviewed authenticated-encryption construction from a maintained cryptographic library rather than implementing cryptography manually. 3. Derive encryption keys from passwords using a modern password-based key derivation function with a unique salt and appropriate work factor. 4. Authenticate archive metadata as well as archive contents. 5. Store and verify a full integrity value or authentication tag before extraction; do not present a truncated, console-only digest as integrity verification. 6. Add the documented command-line options only when their behavior is functional, with explicit failures for invalid or missing credentials. 7. Add compatibility, tampering, wrong-password, and corrupted-archive tests. 8. Align `SKILL.md`, command help, examples, and feature lists with the implementation in every release. ]]>
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 (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documentation claims security-sensitive features like AES-256 encryption, integrity verification, excludes, sync behavior, and scheduling-related use cases that static analysis indicates are not actually implemented. This is dangerous because users may rely on nonexistent protections and assume backups are encrypted or filtered when they are not, leading to data exposure or accidental inclusion of sensitive files.

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill advertises and documents shell execution of a backup script but does not declare any tool scope such as permissions or allowed-tools. In an agent setting, undeclared shell capability increases the chance that the skill is invoked with broader execution authority than reviewers or policy expect, especially for filesystem-wide backup and restore operations.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The manifest description uses broad invocation conditions such as backing up important files, scheduled backups, sync folders, encryption, and restore scenarios without clear limits. Over-broad routing can cause the skill to be selected in situations involving sensitive or destructive file operations, increasing the likelihood of unnecessary shell execution and unsafe filesystem access.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The documentation describes restore and automated backup usage without warnings about destructive overwrite risk, broad filesystem capture, credential handling, or the dangers of unattended cron execution. In a backup/restore context, missing warnings materially increase the chance of data loss, accidental backup of sensitive material, or silent recurring execution against unintended paths.

Description-Behavior Mismatch

Medium
Confidence
99% confidence
Finding
The skill metadata and module docstring explicitly claim encryption support, but the implementation only creates and restores compressed tar archives and computes a checksum. This can cause users to back up sensitive data under the false assumption it is encrypted, resulting in plaintext-at-rest exposure if the archive is accessed by an attacker or copied from insecure storage.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The advertised security property does not exist: the code never encrypts backup contents during creation and never decrypts during restore. In the context of a backup skill intended for important and sensitive files, this mismatch is especially dangerous because users are likely to rely on the claim and store confidential data in unprotected archives.

Static analysis

No suspicious patterns detected.