Back to skill

Security audit

Password Gen

Security checks for vulnerabilities and agentic risk

Overview

This password tool is mostly coherent, but it can silently download and reuse a shared cached word list in a way that could weaken generated passphrases.

Review before installing. The generator uses Python's secrets module for random passwords, but passphrase mode may make an outbound request and cache the word list in a shared temporary location. Avoid using real passwords with the documented --analyze argument form, and prefer a version that bundles or verifies its word list and prompts securely for password analysis.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/password_gen.py:66
Finding

Predictable Shared Temporary Cache Allows Passphrase Word-List Poisoning and Symlink Attacks

Content
View full analysis

Vulnerability Details

File Location: scripts/password_gen.py, lines 66-86
Vulnerability Type: Unsafe temporary-file handling
Risk Level: Medium

Vulnerable Code

python
EFF_CACHE_PATH = os.path.join(tempfile.gettempdir(), "eff_large_wordlist.txt")


def load_eff_wordlist():
    """Download and cache the EFF large word list. Falls back to built-in list."""
    if os.path.exists(EFF_CACHE_PATH):
        words = []
        with open(EFF_CACHE_PATH, "r") as f:
            for line in f:
                parts = line.strip().split("\t")
                if len(parts) == 2:
                    words.append(parts[1])
        if len(words) > 1000:
            return words

    try:
        urllib.request.urlretrieve(EFF_WORDLIST_URL, EFF_CACHE_PATH)
        return load_eff_wordlist()
    except Exception:
        return BUILTIN_WORDS

Technical Analysis

The passphrase generator stores and reads its word-list cache using the fixed filename /tmp/eff_large_wordlist.txt on typical Unix-like systems. A shared temporary directory is generally writable by multiple local users, but the implementation does not verify the file's owner, permissions, type, or cryptographic integrity.

Any existing file is trusted if it contains more than 1,000 tab-separated records. An attacker can therefore create a syntactically valid but predictable word list before the victim runs the program. The list may contain repeated or attacker-selected words, while the program still reports entropy based on the number of records:

python
entropy = words * math.log2(len(wordlist))

Consequently, a malicious list containing duplicate entries can produce highly predictable passphrases while causing the program to report misleadingly high entropy.

The download path also does not protect against symbolic links or use exclusive, atomic file creation. If an attacker places a symbolic link at the cache path, ` ...[truncated 1837 chars]

Remediation
View remediation

Remediation Suggestions

  • Store the cache in a private per-user cache directory, such as $XDG_CACHE_HOME/password-gen, rather than a shared temporary directory.
  • Create the directory with permissions that prevent access by other users, such as mode 0700.
  • Reject symbolic links and non-regular files. Where supported, open files with O_NOFOLLOW.
  • Verify that an existing cache is owned by the current user and is not group- or world-writable.
  • Download into a securely created temporary file in the private cache directory and atomically rename it after validation.
  • Verify the downloaded word list against a pinned SHA-256 digest or another trusted integrity value before accepting it.
  • Validate uniqueness and expected content structure rather than checking only that more than 1,000 records were parsed.
  • Calculate entropy using the number of unique possible words, not the raw number of list entries.
  • Consider making network retrieval explicit and opt-in, with the bundled list used by default.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/password_gen.py:301
Finding

Password Analysis Exposes Secrets Through Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: scripts/password_gen.py, lines 301-302; documented usage at SKILL.md, line 30
Vulnerability Type: Sensitive information exposure through process arguments
Risk Level: Low

Vulnerable Code

python
parser.add_argument("--analyze", type=str, default=None,
                    help="Analyze an existing password's strength")

The documented invocation places the password directly in the command line:

bash
python3 scripts/password_gen.py --analyze 'MyP@ssw0rd!'

Technical Analysis

The password-analysis interface requires the analyzed password to be supplied as a command-line argument. Quoting the password prevents normal shell expansion but does not make the argument secret.

Depending on the host configuration, command-line arguments can be exposed through process inspection interfaces, process-monitoring tools, audit logs, terminal recording, diagnostic collection, and shell history. The password can therefore persist after analysis or be observed while the process is running.

Because the documentation explicitly recommends this invocation pattern, users may submit real account credentials without realizing that they are being placed in process metadata and potentially retained by the shell.

Attack Path

  1. A user follows the documented example and substitutes a real password in the --analyze argument.
  2. The shell may save the complete command in its history file.
  3. While the process is running, another local user or monitoring service with sufficient process-inspection access may read its argument list.
  4. System auditing, terminal recording, or diagnostic tooling may retain the command after execution.
  5. An attacker with access to one of these sources retrieves the plaintext password and attempts to reuse it against the associated account or other accounts.

Impact Assessment

Exploitation can disclose the exact password sup ...[truncated 401 chars]

Remediation
View remediation

Remediation Suggestions

  • Read passwords interactively with getpass.getpass() so they are neither echoed nor included in the process argument list.
  • Change --analyze into a mode switch that prompts securely for the password rather than accepting the password as the option value.
  • If non-interactive operation is required, support standard input and clearly document the security implications of pipelines and redirected files.
  • Avoid environment variables as the primary alternative because they may also be exposed through process inspection or diagnostics.
  • Remove the literal-password command-line example from SKILL.md.
  • Add a warning that users must not place real credentials directly in command arguments, shell history, scripts, or logs.
  • Minimize the lifetime of the password value in memory and avoid adding any logging of the supplied secret.
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
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill advertises 'zero external dependencies' and appears suitable for offline/local use, but passphrase generation can silently fetch a remote word list over the network and cache it locally. This expands the trust boundary, can leak environmental metadata through outbound requests, and allows behavior to change based on remote content availability; in agent contexts, undeclared network access is a meaningful security concern even if the URL is benign.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.