Back to skill

Security audit

Study Limitations Drafter

Security checks for vulnerabilities and agentic risk

Overview

This is a simple academic writing helper, but its script can overwrite any writable output path despite documentation implying workspace-bound output.

Review this skill before installing if your agent may run packaged scripts automatically. Only use --output with a deliberate workspace-local filename, avoid existing files, and prefer sandbox-level write restrictions until the script enforces output path validation.

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:69
Finding

Unrestricted User-Controlled Output Path Allows File Overwrite

Content
View full analysis

Vulnerability Details

File Location: scripts/main.py, lines 69–72
Vulnerability Type: Unrestricted file write and overwrite
Risk Level: Medium

Vulnerable Code

python
if args.output:
    with open(args.output, 'w') as f:
        f.write(text)
    print(f"\nSaved to: {args.output}")

Technical Analysis

The user-controlled --output argument is passed directly to open() in write mode without canonicalization, directory-boundary validation, symlink checks, or overwrite protection.

An attacker who can control the script arguments can provide:

  • An absolute path outside the intended workspace.
  • A relative path containing ../ traversal sequences.
  • A path that resolves through a symbolic link.
  • The path of an existing user-writable file.

Opening the destination with mode 'w' creates the file if it does not exist and silently truncates it if it does. This behavior contradicts the path-validation and workspace-restriction expectations documented in SKILL.md.

The data written is generated from fixed limitation templates rather than being arbitrary attacker-controlled content. Consequently, the primary risk is file corruption or destructive overwrite, not arbitrary code insertion.

Attack Path

  1. The attacker gains control over, or influences, the command-line arguments used to invoke the Skill.

  2. The attacker supplies an output destination outside the intended workspace, for example:

    bash
    python scripts/main.py \
      --issues sample_size \
      --output ../../user-writable-configuration
    
  3. The script accepts the path without validation.

  4. Python resolves the path and opens the target in 'w' mode.

  5. If the process account can write to the target, the existing file is truncated and replaced with the generated study-limitations text.

A similar attack can target a symbolic link whose resolved destination is outside the allowed output directory.

Impact Assessment

The vulnerability does not g ...[truncated 809 chars]

Remediation
View remediation

Remediation Suggestions

  1. Define a dedicated, trusted output directory rather than accepting unrestricted destinations.
  2. Resolve both the trusted directory and requested destination with pathlib.Path.resolve().
  3. Verify that the resolved destination is contained within the trusted directory before writing.
  4. Reject absolute paths and traversal components if callers only need simple output filenames.
  5. Reject symbolic-link destinations, and account for race conditions when checking and opening files.
  6. Avoid silent replacement by using exclusive creation mode ('x') when overwriting is unnecessary. If replacement is required, require explicit authorization.
  7. Open files with an explicit encoding and handle filesystem errors without exposing unnecessary environment details.
  8. Where supported, use descriptor-based, no-follow file-opening controls to reduce symlink race risks.

Example boundary validation:

python
from pathlib import Path

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

requested = Path(args.output)
if requested.is_absolute() or ".." in requested.parts:
    raise ValueError("Output must be a relative path within the output directory")

destination = output_root.joinpath(requested).resolve()
if destination != output_root and output_root not in destination.parents:
    raise ValueError("Output path escapes the permitted output directory")

if destination.exists() or destination.is_symlink():
    raise FileExistsError("Refusing to overwrite an existing file")

with destination.open("x", encoding="utf-8") as f:
    f.write(text)

For higher-assurance environments, enforce the output boundary at the sandbox or operating-system level in addition to application-level validation.

Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • 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
Findings (1)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill advertises executable Python workflows and explicitly discusses reading input files and writing output files, but it does not declare any tool scope such as permissions or allowed-tools. That mismatch weakens reviewability and enforcement because consumers cannot tell, from metadata alone, what filesystem actions the skill may perform, increasing the risk of unintended or overbroad file writes if the packaged script is run.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.