Back to skill

Security audit

Peer Review Response Drafter

Security checks for vulnerabilities and agentic risk

Overview

This skill has a legitimate drafting purpose, but its installer and local script give more filesystem and package-install risk than the documentation safely scopes.

Review before installing. Use this only in a constrained workspace, avoid running the pip install as-is unless the unnecessary dependencies are removed or locked, and do not pass sensitive or absolute paths to the script. Treat output paths carefully because existing writable files can be overwritten without confirmation.

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

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unnecessary Unpinned Third-Party Dependencies Create Supply-Chain Exposure

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-2
Vulnerability Type: Unpinned and unnecessary dependencies
Risk Level: Medium

Vulnerable Code

text
dataclasses
enum

The installation instruction in SKILL.md:218-222 causes these packages to be retrieved from the configured Python package index:

bash
# Python dependencies
pip install -r requirements.txt

Technical Analysis

The implementation imports dataclasses and enum at scripts/main.py:17-18, but both are part of the Python standard library in supported modern Python versions. Declaring registry packages with the same names is therefore unnecessary under such runtimes.

Neither dependency has a version constraint or integrity hash. Consequently, package selection can change between installations according to the configured package index, index precedence, and currently published package versions. Installing a Python package can execute package-controlled build or installation logic, creating avoidable supply-chain exposure before the Skill itself runs.

This finding does not establish that the currently published packages are malicious. The vulnerability is that the project unnecessarily trusts mutable, unverified third-party artifacts for functionality already supplied by the runtime.

Attack Path

  1. A user follows the documented prerequisite and runs pip install -r requirements.txt.
  2. Pip queries the user's configured package index or indexes for the unpinned names dataclasses and enum.
  3. An attacker who controls or compromises a selected package release, an internal index, or package-index resolution can supply attacker-controlled package content.
  4. Pip downloads and installs that content, potentially executing package-controlled build or installation behavior.
  5. Malicious code then runs with the permissions of the user or automation account performing installation.

Impact Assessment

...[truncated 419 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove both entries from requirements.txt when the project targets a modern Python version:
    text
    # No external dependencies required
    
  2. Declare and enforce the minimum supported Python version in project metadata and documentation.
  3. If support for a legacy Python version is genuinely required, use only the necessary verified backport with an appropriate Python-version environment marker.
  4. Pin any unavoidable third-party dependencies to reviewed versions and require cryptographic hashes, for example through a locked requirements file and pip install --require-hashes.
  5. Use a trusted package index and prevent unexpected fallback to public or lower-priority indexes in controlled deployment environments.
  6. Add dependency scanning and lock-file review to the release process.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/main.py:380
Finding

User-Controlled Paths Permit Unrestricted File Reads and Destructive File Overwrites

Content
View full analysis

Vulnerability Details

File Location: scripts/main.py:380-382, scripts/main.py:431-433, and scripts/main.py:461-464
Vulnerability Type: Unrestricted filesystem access and unsafe file overwrite
Risk Level: Medium

Vulnerable Code

Interactive-mode output accepts an arbitrary path and opens it in destructive write mode:

python
save = input("\nSave to file? (filename or 'n'): ").strip()
if save and save.lower() != 'n':
    with open(save, 'w') as f:
        f.write(letter)
    print(f"Saved to {save}")

Command-line input accepts an arbitrary path without containment or file-type validation:

python
# Read input
if args.input:
    with open(args.input, 'r') as f:
        comments_text = f.read()
else:
    comments_text = sys.stdin.read()

Command-line output also accepts an arbitrary path and opens it in destructive write mode:

python
# Output
if args.output:
    with open(args.output, 'w') as f:
        f.write(letter)
    print(f"Response letter saved to {args.output}")
else:
    print(letter)

Technical Analysis

Values supplied through --input, --output, or the interactive save prompt are passed directly to open(). The implementation does not:

  • Resolve and validate canonical paths.
  • Restrict files to an approved workspace.
  • Reject absolute paths or parent-directory traversal.
  • detect or reject symbolic links.
  • Prevent accidental replacement of an existing file.
  • Use exclusive creation or request confirmation before truncation.

Opening an output path with mode 'w' immediately truncates an existing writable file. Python also follows symbolic links by default, so a path that appears to reside in an expected directory can resolve to another writable target.

Input paths can reference any readable file available to the process. The file is treated as reviewer-comment input, and parseable portions may subsequently appear ...[truncated 2253 chars]

Remediation
View remediation

Remediation Suggestions

  1. Establish an explicit workspace root and resolve all paths before use:
    python
    from pathlib import Path
    
    WORKSPACE = Path.cwd().resolve()
    
    def workspace_path(value: str) -> Path:
        candidate = (WORKSPACE / value).resolve()
        if candidate != WORKSPACE and WORKSPACE not in candidate.parents:
            raise ValueError("Path must remain inside the workspace")
        return candidate
    
  2. Reject absolute paths and parent traversal when they are not required by the documented functionality.
  3. Validate input as a regular file and reject symbolic links where practical.
  4. Restrict output to a dedicated workspace subdirectory.
  5. Avoid silent truncation. Use exclusive creation mode ('x') by default or require explicit confirmation before replacing an existing file.
  6. Where strong symlink resistance is required, use operating-system facilities such as O_NOFOLLOW and perform validation on an opened file descriptor.
  7. Open text files with an explicit encoding, such as encoding="utf-8", and impose reasonable input-size limits.
  8. Catch OSError, UnicodeError, and validation errors and return sanitized messages rather than raw stack traces.
  9. Run the Skill under a least-privileged account with access only to the intended workspace.
  10. Add tests covering absolute paths, ../ traversal, symlinks, existing output files, oversized inputs, and paths outside the workspace.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (7)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill advertises file read/write behavior (--input-file, --output) and explicitly documents local script execution, but it does not declare an explicit tool scope such as permissions or allowed-tools. This creates a trust and enforcement gap: an agent framework may permit broader file access than users expect, increasing the risk of unintended reads or writes if the skill is invoked on sensitive paths.

Content

No source excerpt is available for this finding.

Tainted flow: 'save' from input (line 379, user input) → open (file write)

Medium
Category
Data Flow
Confidence
88% confidence
Finding

The interactive save path is taken directly from user input and passed to open() for writing without any validation or confinement. This allows an operator or any upstream caller controlling stdin to overwrite arbitrary files writable by the current user, which can damage local data or modify configuration files if the tool is run in a sensitive environment.

Content

Scanner excerpt · scripts/main.py (reported line 381)May include surrounding context.

python
# Save option
    save = input("\nSave to file? (filename or 'n'): ").strip()
    if save and save.lower() != 'n':
        with open(save, 'w') as f:
            f.write(letter)
        print(f"Saved to {save}")

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill supports writing a generated response letter to a user-specified output path, but it does not clearly warn users that local files may be created or overwritten. In practice, this can lead to accidental data loss or unintended modification of existing files, especially in automation contexts where output paths may be reused.

Content

No source excerpt is available for this finding.

Scope Creep

Low
Category
Excessive Agency
Confidence
70% confidence
Finding

Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Content

Scanner excerpt · references/response_templates.md (reported line 210)May include surrounding context.

addresses the concerns raised while [additional rationale].

text

### Revisions Beyond Scope

We thank the reviewer for this ambitious suggestion. While we agree

Scope Creep

Low
Category
Excessive Agency
Confidence
70% confidence
Finding

Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Content

Scanner excerpt · references/response_templates.md (reported line 214)May include surrounding context.

text
We thank the reviewer for this ambitious suggestion. While we agree 
that [extended analysis] would be valuable, this extends beyond the 
scope of the current study, which focuses on [current scope]. We have 
added a note about this potential extension as future work in the 
Discussion section (Page X, Lines Y-Z).

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
60% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
dataclasses
enum

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
60% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
dataclasses
enum

Static analysis

No suspicious patterns detected.