Back to skill

Security audit

Drug Pronunciation

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but its optional export feature can overwrite arbitrary writable files instead of being confined to the workspace.

Install only if you trust the caller to choose safe output paths, or run it in a sandbox. Avoid using --output with absolute paths, traversal paths, or existing important files until the skill restricts exports to a dedicated workspace directory and avoids silent overwrites.

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

Unrestricted Output Path Allows Arbitrary File Overwrite

Content
View full analysis

Vulnerability Details

File Location: scripts/main.py, lines 172–174
Vulnerability Type: Unrestricted output path and unsafe file overwrite
Risk Level: Medium

python
if args.output:
    with open(args.output, 'w', encoding='utf-8') as f:
        f.write(output)

Technical Analysis

The application passes the user-controlled --output argument directly to open() without canonicalizing or validating the path. It does not confine output to an approved workspace, reject path traversal, detect symbolic links, or prevent replacement of an existing file.

Opening the path in w mode creates the file if it does not exist and truncates it if it does. Python also follows symbolic links during this operation. Therefore, anyone who can control the command-line arguments can cause the process to replace the contents of an arbitrary file for which the process has write permission.

This behavior conflicts with the security controls identified in SKILL.md, particularly the stated need to validate paths against ../ traversal and restrict output to the workspace.

Attack Path

  1. The attacker identifies a file writable by the account running the skill.
  2. The attacker invokes the script with an output path outside the intended workspace, for example:
    bash
    python scripts/main.py --drug metformin --output ../../target.json
    
    Alternatively, the attacker supplies a path that points to a symbolic link whose target is a writable sensitive file.
  3. The script accepts the path without validation.
  4. open(args.output, 'w') follows the path and truncates the destination.
  5. The generated pronunciation JSON is written over the previous file contents.

Impact Assessment

Exploitation does not grant privileges beyond those already held by the process. However, it allows an attacker who controls invocation arguments to corrupt or replace any file writable by that process, including f ...[truncated 366 chars]

Remediation
View remediation

Remediation Suggestions

  • Define a dedicated output directory controlled by the application.
  • Resolve both the approved directory and requested destination with pathlib.Path.resolve(), then verify that the destination remains beneath the approved directory.
  • Reject absolute paths and traversal components when arbitrary directories are unnecessary.
  • Restrict output names to expected JSON filenames and validate the .json suffix.
  • Reject symbolic-link destinations and inspect parent directories for unsafe links where the threat model requires it.
  • Avoid silently truncating existing files. Use exclusive creation mode (x) by default or require an explicit overwrite option.
  • For stronger protection against race conditions, use directory-relative, no-follow operating-system file APIs where supported.
  • Return a sanitized error when validation fails.

Example containment logic:

python
from pathlib import Path

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

requested = (output_root / args.output).resolve()
if requested.parent != output_root or requested.suffix.lower() != ".json":
    parser.error("Output must be a JSON file directly inside the output directory")
if requested.is_symlink():
    parser.error("Symbolic-link output paths are not allowed")

with requested.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
85% confidence
Finding

The skill advertises file write capability via the --output parameter and explicitly states output files are saved to the workspace, but it does not declare any permissions or allowed-tools scope. This creates a policy/control gap: a caller or agent may execute file-writing behavior without an explicit capability declaration, reducing enforceability of least-privilege controls and increasing the risk of unintended or unsafe writes if path validation is incomplete.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest describes a skill that provides pronunciation guides and phonetic transcriptions, which implies generating pronunciation data but not necessarily performing filesystem writes. The CLI adds an --output option and writes JSON to an arbitrary file path, expanding the behavior beyond purely returning pronunciation information.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.