Back to skill

Security audit

Anatomy Quiz Master

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent local anatomy quiz generator, but its dependency manifest and file-output handling create review-worthy risks that are not accurately described in its own security notes.

Review this skill before installing. It appears intended to run locally and generate quiz content, but avoid running pip install -r requirements.txt unless the dependency file is removed or fixed, and only use --output paths in a dedicated workspace directory because existing writable files can be overwritten.

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

Standard-Library Modules Incorrectly Declared as External Dependencies

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-3
Vulnerability Type: Dependency confusion and unnecessary third-party package installation
Risk Level: Medium

Vulnerable Code

text
argparse
json
random

Technical Analysis

argparse, json, and random are included with the Python standard library and do not need to be installed from a package repository. Declaring these names in requirements.txt may cause package-management automation to search an external index, such as PyPI, for unrelated third-party distributions with matching names.

The dependencies are also unpinned and have no integrity hashes. If a matching distribution is malicious, compromised, or replaced, its installation process or imported code could execute in the installation environment. This contradicts the statement in SKILL.md that the project has no additional package requirements.

Exploitation depends on a user or automated build system running a command such as:

bash
pip install -r requirements.txt

Attack Path

  1. An attacker publishes or compromises a package matching one of the unnecessary dependency names.
  2. A user, CI worker, or deployment process executes pip install -r requirements.txt.
  3. The package manager resolves the standard-library name as an external distribution.
  4. The third-party package is downloaded and installed.
  5. Malicious installation behavior or subsequently imported package code executes with the privileges of the installer or application account.

Impact Assessment

A successful supply-chain attack could execute code with the privileges of the account performing package installation. Depending on that environment, this could expose source code, environment variables, credentials available to the build process, generated artifacts, and files writable by the account.

The project itself does not import third-party dependencies, and exploitation re ...[truncated 154 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove argparse, json, and random from requirements.txt.
  • Delete requirements.txt if the project has no external dependencies, or leave it empty if build tooling requires the file.
  • If external dependencies are introduced later, pin reviewed versions and use cryptographic hashes, for example through a lock file or pip --require-hashes.
  • Configure CI and deployment systems to use a trusted package index and prevent dependency fallback to unapproved public repositories.
  • Add an automated dependency check that rejects standard-library modules in dependency manifests.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/main.py:241
Finding

User-Controlled Output Path Allows Overwriting Arbitrary Writable Files

Content
View full analysis

Vulnerability Details

File Location: scripts/main.py:185-189, 241-244
Vulnerability Type: Unrestricted file write and symlink-following file overwrite
Risk Level: Medium

Vulnerable Code

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

Technical Analysis

The value supplied through --output is passed directly to open() in write mode. The application does not:

  • Restrict output to an approved workspace directory.
  • Reject absolute paths or parent-directory traversal.
  • Check whether the destination already exists.
  • Reject symbolic links.
  • Use exclusive file creation.
  • Verify the resolved destination before writing.

Python's open(path, 'w') follows symbolic links and truncates an existing destination before writing. Consequently, an attacker who can influence command-line arguments, or who can place a symlink at a predictable output path, can cause the process to replace any writable file accessible to its operating-system account.

This behavior contradicts the security checklist in SKILL.md, which claims that output is restricted to the workspace.

Attack Path

Direct-path exploitation:

  1. An attacker controls or influences the --output argument.
  2. The attacker supplies an absolute path or a traversal path targeting an existing writable file.
  3. The script invokes open(args.output, 'w').
  4. The target file is truncated and replaced with generated quiz output.

Example:

bash
python scripts/main.py --output ../../target-file

Symlink exploitation:

  1. An attacker creates a symbolic link at the expected output location that points to a sensitive file writable by the victim ...[truncated 1006 chars]
Remediation
View remediation

Remediation Suggestions

  • Define a dedicated output directory and resolve both it and the requested destination with pathlib.Path.resolve().
  • Verify that the resolved destination remains beneath the approved output directory using Path.relative_to() or an equivalent containment check.
  • Reject absolute paths, traversal outside the output directory, symbolic links, and non-regular destination files.
  • Avoid overwriting existing files by default. Use exclusive creation mode ("x") where replacement is not explicitly required.
  • If replacement is supported, require an explicit overwrite flag and validate the destination again immediately before writing.
  • Consider creating output through a securely created temporary file in the same directory, then performing an atomic replacement after validation.
  • Run the tool with the minimum filesystem permissions necessary.

A containment check can follow this pattern:

python
output_root = Path("output").resolve()
destination = (output_root / args.output).resolve()

try:
    destination.relative_to(output_root)
except ValueError:
    parser.error("Output path must remain inside the output directory")

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

destination.parent.mkdir(parents=True, exist_ok=True)
with destination.open("x", encoding="utf-8") as file:
    file.write(output)
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (3)

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
argparse
json
random

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
argparse
json
random

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 3)May include surrounding context.

text
argparse
json
random