Back to skill

Security audit

Archive Tool

Security checks for vulnerabilities and agentic risk

Overview

This archive utility is mostly purpose-aligned, but its extraction behavior can write files outside the chosen folder when handling crafted tar archives.

Install only if you are comfortable treating this as a review-needed archive tool. Avoid extracting untrusted archives with it, especially tar/tar.gz/tgz/tar.bz2/tar.xz files; list contents first, extract into a new empty directory, and do not pass sensitive archive passwords on the command line.

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/archive.py:25
Finding
Arbitrary File Write Through Unsafe TAR Archive Extraction## Vulnerability Details **File Location**: `scripts/archive.py`, lines 25-29 **Vulnerability Type**: Path traversal and unsafe link handling during TAR extraction **Risk Level**: High ### Vulnerable Code ```python def extract_tar(filepath, output_dir): """Extract tar/tar.gz/tgz file using Python stdlib""" with tarfile.open(filepath, 'r:*') as tar_ref: tar_ref.extractall(output_dir) return True ``` ### Technical Analysis The application passes every TAR member directly to `tarfile.extractall()` without enforcing a safe extraction filter or validating member paths and link targets. On Python versions where a restrictive extraction filter is not the default, a malicious TAR archive can contain: - Relative traversal paths such as `../../home/user/.config/application.conf` - Absolute paths targeting files outside the selected output directory - Symbolic or hard links that redirect subsequent extraction operations outside the destination - Special files or other unsafe TAR member types Creating `output_dir` before extraction does not constrain archive members to that directory. The destination of every member must be resolved and verified independently. ### Attack Path 1. An attacker creates a TAR, TAR.GZ, TGZ, TAR.BZ2, or TAR.XZ archive containing a member whose path traverses outside the intended extraction directory, or a link that points outside it. 2. The attacker provides the archive to a user or causes an agent to process it. 3. The user or agent runs a command such as: ```bash python3 scripts/archive.py extract malicious.tar -o ./extracted ``` 4. `extract_file()` identifies the input as a TAR archive and calls `extract_tar()`. 5. `tar_ref.extractall(output_dir)` processes the malicious member without an explicitly enforced safe filter. 6. On an affected Python runtime, the crafted member is written outside `./extracted`. ### Impact Assessment The attacker m ...[truncated 675 chars]
Remediation
## Remediation Suggestions On supported Python versions, explicitly require the safe data filter rather than relying on runtime defaults: ```python def extract_tar(filepath, output_dir): destination = Path(output_dir).resolve() destination.mkdir(parents=True, exist_ok=True) with tarfile.open(filepath, "r:*") as tar_ref: tar_ref.extractall(destination, filter="data") return True ``` For compatibility with runtimes that do not support `filter="data"`, implement validation before extraction: 1. Resolve the intended destination directory to an absolute canonical path. 2. Reject absolute member paths. 3. Resolve each member's prospective destination and verify that it remains beneath the extraction directory. 4. Reject traversal components that escape the destination. 5. Reject device files, FIFOs, and other special member types. 6. Reject symbolic and hard links, or separately verify that both their extraction locations and targets remain within the destination. 7. Extract only after all archive members have passed validation. 8. Add regression tests covering absolute paths, `../` traversal, symbolic-link pivots, hard-link pivots, and special files.

T09 · Insecure Skill Coding Practices

Warning
Location
[-o OUTPUT] [--password PASS] ``` ```bash # Extract with password python archive.py extract archive.rar --password secret ``` ### Technical Analysis Command-line arguments are not an appropriate secret-input channel. Depending on the operating system, shell, agent framework, and logging configuration, a plaintext password supplied through `--password` may be exposed through: - Shell history files - Process listings or process-inspection interfaces - Parent-process telemetry - Agent ...[truncated 1670 chars]:181
Finding
Archive Password Disclosure Through Command-Line Arguments## Vulnerability Details **File Location**: `scripts/archive.py`, lines 181-185; `SKILL.md`, lines 76-78 and 92-94 **Vulnerability Type**: Sensitive information exposure through process arguments and command history **Risk Level**: Medium ### Vulnerable Code The command-line parser accepts an archive password directly as an argument: ```python # Extract command extract_parser = subparsers.add_parser('extract', help='Extract archive') extract_parser.add_argument('file', help='Archive file to extract') extract_parser.add_argument('-o', '--output', default='.', help='Output directory') extract_parser.add_argument('--password', help='Password for protected archives') ``` The documentation encourages users to place the password directly in the command: ```bash python archive.py extract <file> [-o OUTPUT] [--password PASS] ``` ```bash # Extract with password python archive.py extract archive.rar --password secret ``` ### Technical Analysis Command-line arguments are not an appropriate secret-input channel. Depending on the operating system, shell, agent framework, and logging configuration, a plaintext password supplied through `--password` may be exposed through: - Shell history files - Process listings or process-inspection interfaces - Parent-process telemetry - Agent execution transcripts - Terminal session recording - Debugging and command audit logs The application subsequently encodes the same password for ZIP extraction, but that does not remove copies already exposed through the original process argument. ### Attack Path 1. A user follows the documented example and runs: ```bash python3 scripts/archive.py extract protected.zip --password secret ``` 2. The shell may save the complete command in its history. 3. While the process is running, another local process with sufficient process-inspection access may read its argument vector. 4. An agent runtime, terminal rec ...[truncated 897 chars]
Remediation
## Remediation Suggestions Avoid accepting passwords as ordinary command-line arguments. 1. Prompt interactively using `getpass.getpass()` when an encrypted archive requires a password: ```python import getpass password = getpass.getpass("Archive password: ") ``` 2. If automation is required, support reading the password from a protected file descriptor or standard input, and clearly document the security implications. 3. Avoid environment variables as the preferred solution because they may also be exposed through process environments, diagnostics, or orchestration logs. 4. Remove examples containing literal passwords from `SKILL.md`. 5. Display a warning or reject `--password` after a deprecation period. 6. Ensure exceptions, debug output, and telemetry never include the password. 7. Document that users should rotate any password previously entered through the command line if execution history or logs may be accessible.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill describes extraction and creation features but does not clearly warn that these operations write files to disk, may create directories, and could overwrite or modify data in the chosen output location. For archive handling, this omission is risky because users may invoke the skill without understanding the side effects, especially when extracting untrusted archives or targeting broad locations like the current directory.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The activation text is broad enough to trigger on many ordinary archive-related requests without clearly constraining what paths, files, or side effects are in scope. In a skill that can extract and create archives, overbroad activation increases the chance the agent performs filesystem write operations in situations where the user did not explicitly intend those actions or where a different, safer skill should handle the request.

Missing User Warnings

Medium
Confidence
99% confidence
Finding
The code extracts ZIP archives directly with zipfile.extractall and TAR archives elsewhere with tarfile.extractall, without validating member paths, symlinks, or overwrite behavior. A crafted archive can perform path traversal and write outside the target directory, potentially overwriting sensitive files or planting executables in user-controlled startup locations.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
These functions call external binaries via subprocess.run to handle archive extraction, which is a safety-relevant operation for code files. Although the subprocess arguments are fixed and the behavior is part of archive handling, there is no explicit disclosure in help text or comments that extracting these formats depends on launching system tools.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def extract_rar(filepath, output_dir):
    """Extract rar using unar (system tool)"""
    try:
        result = subprocess.run(
            ['unar', '-o', output_dir, filepath],
            capture_output=True, text=True
        )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def extract_7z(filepath, output_dir):
    """Extract 7z using p7zip (system tool)"""
    try:
        result = subprocess.run(
            ['7z', 'x', f'-o{output_dir}', '-y', filepath],
            capture_output=True, text=True
        )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.