Back to skill

Security audit

Comparison Table Gen

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to generate comparison tables as advertised, but its optional output path can overwrite any writable file path without containment or warning.

Install only if you are comfortable with a local script that writes to caller-provided paths. Use stdout or a dedicated output directory, avoid absolute or parent-directory paths, and do not let untrusted text choose the `--output` value until overwrite protection and path containment are added.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/main.py:66
Finding

Unrestricted Output Path Allows Arbitrary File Overwrite

Content
View full analysis

Vulnerability Details

File Location: scripts/main.py, lines 66–70 and 94–96
Vulnerability Type: Unrestricted file write / path traversal
Risk Level: Medium

Vulnerable Code

python
parser.add_argument(
    "--output", "-o",
    type=str,
    help="Output JSON file path (optional, prints to stdout if not specified)"
)
python
if args.output:
    with open(args.output, 'w', encoding='utf-8') as f:
        f.write(output)
    print(f"Table saved to: {args.output}")

Technical Analysis

The caller-controlled --output value is passed directly to open() in write mode. The implementation does not reject absolute paths or parent-directory traversal, canonicalize the path against an authorized workspace, check for symbolic links, or require exclusive file creation.

Consequently, the process can create or truncate any file writable under its operating-system privileges. The w mode truncates an existing target before writing the generated JSON. Although the attacker cannot supply arbitrary file contents through this interface, destructive overwrite and configuration corruption remain possible.

This behavior also conflicts with the security controls identified in SKILL.md, which state that output should be restricted to the workspace and paths should be validated against ../ traversal.

Attack Path

  1. An attacker gains influence over the skill's command-line arguments.
  2. The attacker supplies an absolute path or traversal path, such as --output ../../target-file.
  3. Python resolves the path without any application-level containment check.
  4. open(args.output, 'w') creates the target or truncates an existing writable file.
  5. The generated JSON replaces the previous contents, potentially corrupting data or configuration.

Impact Assessment

Exploitation is limited to the filesystem permissions of the account running the skill and does not itself provide ...[truncated 348 chars]

Remediation
View remediation

Remediation Suggestions

  1. Define a dedicated, trusted output directory beneath the project workspace.
  2. Reject absolute paths and resolve the requested path with pathlib.Path.resolve().
  3. Verify that the resolved target remains beneath the trusted output directory using Path.relative_to() or an equivalent containment check.
  4. Reject parent-directory traversal and symbolic-link targets.
  5. Use exclusive creation mode (x) where overwriting is unnecessary, or require explicit authorization before replacing an existing file.
  6. Create output directories with restrictive permissions and run the skill under a least-privileged account.
  7. Return a sanitized error when path validation fails.

Example containment pattern:

python
from pathlib import Path

output_root = (Path.cwd() / "output").resolve()
output_root.mkdir(parents=True, exist_ok=True)

requested = Path(args.output)
if requested.is_absolute():
    raise ValueError("Absolute output paths are not allowed")

target = (output_root / requested).resolve()
try:
    target.relative_to(output_root)
except ValueError:
    raise ValueError("Output path must remain within the output directory")

if target.is_symlink():
    raise ValueError("Symbolic-link output targets are not allowed")

with target.open("x", encoding="utf-8") as f:
    f.write(output)
Vulnerability Patterns
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (2)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill explicitly documents file-writing capability via the --output parameter and risk table, but it does not declare any tool scope such as permissions or allowed-tools. That mismatch weakens security review and enforcement because consumers cannot clearly determine or constrain what file operations the skill is expected to perform, increasing the chance of unintended workspace modification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The documentation mentions saving output to a file but does not clearly warn that execution may create or overwrite files in the workspace. This can lead users or agents to invoke the skill without understanding the side effects, which increases the risk of accidental data loss or overwriting important files.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.