Back to skill

Security audit

Random Tool

Security checks for vulnerabilities and agentic risk

Overview

This random generator is low-permission, but it advertises security-token and secure-password use while generating those values with non-cryptographic randomness.

Review before installing for any security-sensitive use. It is reasonable for testing, demos, simple random choices, or shuffling, but do not use its generated passwords, tokens, keys, reset links, or session identifiers unless the implementation is changed to use a cryptographically secure source such as Python's secrets module and the documentation is corrected.

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

Error
Location
scripts/genrandom.py:4
Finding
Predictable PRNG Used for Security-Sensitive Passwords and Random Values<![CDATA[ ## Vulnerability Details **File Location**: `scripts/genrandom.py`, lines 4-29 **Vulnerability Type**: Use of a non-cryptographic pseudorandom number generator for security-sensitive values **Risk Level**: High ### Vulnerable Code ```python import random import string import sys import uuid def random_int(min_val: int, max_val: int) -> int: """Generate random integer.""" return random.randint(min_val, max_val) def random_float(min_val: float, max_val: float) -> float: """Generate random float.""" return random.uniform(min_val, max_val) def random_string(length: int, charset: str = None) -> str: """Generate random string.""" if charset is None: charset = string.ascii_letters + string.digits return ''.join(random.choice(charset) for _ in range(length)) def random_password(length: int) -> str: """Generate secure password.""" chars = string.ascii_letters + string.digits + "!@#$%^&*()_+-=" return ''.join(random.choice(chars) for _ in range(length)) ``` ### Technical Analysis The implementation uses Python's `random` module for integers, strings, and passwords. This module is based on the deterministic Mersenne Twister pseudorandom number generator and is explicitly unsuitable for cryptographic purposes. This is security-relevant because: - `random_password()` describes its output as a secure password. - `SKILL.md` advertises the Skill as generating “cryptographically secure random values.” - The documentation identifies security tokens as an intended use case. If an attacker obtains enough PRNG-derived output or otherwise learns the generator state, future outputs may become predictable. Random strings or passwords derived from the same process must therefore not be treated as cryptographic secrets. Operating-system seeding does not make Mersenne Twister a cryptographically secure generator because its internal state and output transformation are not designed to resist prediction. The UUID pa ...[truncated 1607 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace security-sensitive use of `random.choice()` with `secrets.choice()`: ```python import secrets import string def random_string(length: int, charset: str | None = None) -> str: if length < 0: raise ValueError("Length must be non-negative") if charset is None: charset = string.ascii_letters + string.digits if not charset: raise ValueError("Character set must not be empty") return ''.join(secrets.choice(charset) for _ in range(length)) def random_password(length: int) -> str: if length <= 0: raise ValueError("Password length must be positive") chars = string.ascii_letters + string.digits + "!@#$%^&*()_+-=" return ''.join(secrets.choice(chars) for _ in range(length)) ``` 2. If integer output may be used for security purposes, generate it with rejection sampling through `secrets.randbelow()`: ```python def secure_random_int(min_val: int, max_val: int) -> int: if min_val > max_val: raise ValueError("Minimum must not exceed maximum") return min_val + secrets.randbelow(max_val - min_val + 1) ``` 3. Do not use floating-point random values as cryptographic tokens. Generate a fixed number of random bytes with `secrets.token_bytes()`, `secrets.token_hex()`, or `secrets.token_urlsafe()` instead. 4. Clearly separate test-data generation from cryptographic generation. If non-security randomness remains available, label it explicitly as unsuitable for passwords, tokens, keys, session identifiers, or other secrets. 5. Add automated tests that verify security-sensitive functions use the `secrets` or operating-system randomness APIs rather than the global `random` module. 6. Correct the CLI documentation so that documented options match the implementation, and retain cryptographic-security claims only after all relevant generation paths use cryptographically secure APIs. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The code broadly aligns with the stated theme of randomization, but the description is not fully accurate. The implementation includes additional user-facing capabilities beyond random numbers/passwords/strings: UUID generation, random selection from a list, and line shuffling from stdin. Also, while the internal random_string function accepts a charset parameter, the exposed CLI does not allow users to configure character sets, so that specific claim is overstated. Because the skill exposes several undeclared capabilities and one declared capability is not actually available through the interface, this is a description-behavior mismatch.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The skill description says it can be used for security tokens, but both string and password generation rely on the non-cryptographic `random` PRNG. This creates a dangerous trust signal: consumers may generate tokens or credentials that are materially weaker and potentially predictable, enabling account compromise or token guessing in downstream systems.

Intent-Code Divergence

Medium
Confidence
99% confidence
Finding
The function is documented as generating a secure password, but it uses Python's `random` module, which is not cryptographically secure and can be predictable. Because the skill metadata explicitly advertises use for security tokens, this mismatch can cause users to rely on weak secrets for authentication, reset links, or other security-sensitive purposes.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The password generator presents itself as secure but uses a non-cryptographic PRNG and provides no warning to users. In context, this is more dangerous than a generic random utility because the skill branding and description encourage security-sensitive usage, increasing the chance of real-world misuse.

Static analysis

No suspicious patterns detected.