Back to skill

Security audit

Developer Utils

Security checks for vulnerabilities and agentic risk

Overview

This developer utility skill is broadly coherent, but users should review it because some runnable examples make external requests, auto-install packages, and include unsafe crypto examples for secrets.

Review each command before allowing an agent to run it. Avoid the auto-install paths unless you intentionally want Homebrew to modify the machine, do not use the AES or BIP39 snippets for real secrets, wallets, or production encryption, and do not put tokens, internal URLs, or private payloads into the network examples.

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

T08 · Insecure Dependencies

Warning
Location
SKILL.md:1002
Finding
Automatic Installation of Unpinned Third-Party Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:1002-1080` and `SKILL.md:1602-1611` **Vulnerability Type**: Automatic dependency installation without consent, version pinning, or integrity verification **Risk Level**: Medium ### Vulnerable Code ```python import subprocess import sys def ensure_qrencode(): """Ensure qrencode is installed, auto-install if not""" result = subprocess.run(['which', 'qrencode'], capture_output=True) if result.returncode == 0: return True print("📦 qrencode not found. Installing...") subprocess.run(['brew', 'install', 'qrencode']) # Verify installation result = subprocess.run(['which', 'qrencode'], capture_output=True) return result.returncode == 0 ``` ```python import subprocess def ensure_zbar(): """Ensure zbar is installed""" result = subprocess.run(['which', 'zbarimg'], capture_output=True) if result.returncode == 0: return True print("📦 zbar not found. Installing...") subprocess.run(['brew', 'install', 'zbar']) return True ``` ```python import subprocess def ensure_figlet(): """Ensure figlet is installed, auto-install if not""" result = subprocess.run(['which', 'figlet'], capture_output=True) if result.returncode == 0: return True print("📦 figlet not found. Installing...") subprocess.run(['brew', 'install', 'figlet']) return True ``` ### Technical Analysis The QR code, QR reader, and ASCII-art examples automatically invoke Homebrew when their expected executables are missing. These operations modify the host environment without first obtaining explicit user consent. The formulas are referenced only by package name. The Skill does not pin versions, verify expected hashes or signatures, validate the selected Homebrew repository, or reliably check whether installation completed successfully. Although Homebrew provides its own supply-chain controls, silently initiating installation unnecessarily increa ...[truncated 1283 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all automatic `brew install` calls from utility execution paths. 2. Detect missing dependencies and return a clear error containing an optional installation command. 3. Require explicit user confirmation before initiating any package-manager operation. 4. Where practical, document tested or pinned dependency versions. 5. Use trusted repositories and preserve package-manager signature and integrity checks. 6. Check and handle the installation command's return code rather than assuming success. 7. Prefer built-in implementations when available, such as the included ASCII-art fallback. 8. Run third-party utilities with only the filesystem and network access required for the requested task. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:1892
Finding
AES Example Discloses Encryption Keys and Uses Unauthenticated Cryptography<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:1892-1970` **Vulnerability Type**: Secret disclosure, weak password handling, and unauthenticated AES-CBC encryption **Risk Level**: High ### Vulnerable Code ```python try: from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad from Crypto.Random import get_random_bytes import base64 def aes_encrypt(plaintext, key=None, iv=None): """Encrypt text using AES-256-CBC""" if key is None: key = get_random_bytes(32) # 256-bit key elif isinstance(key, str): key = key.encode().ljust(32, b'\0')[:32] if iv is None: iv = get_random_bytes(16) elif isinstance(iv, str): iv = iv.encode().ljust(16, b'\0')[:16] cipher = AES.new(key, AES.MODE_CBC, iv) padded = pad(plaintext.encode(), AES.block_size) encrypted = cipher.encrypt(padded) return { 'ciphertext': base64.b64encode(encrypted).decode(), 'key': base64.b64encode(key).decode(), 'iv': base64.b64encode(iv).decode(), } def aes_decrypt(ciphertext, key, iv): """Decrypt AES-256-CBC encrypted text""" if isinstance(key, str): key = base64.b64decode(key) if isinstance(iv, str): iv = base64.b64decode(iv) cipher = AES.new(key, AES.MODE_CBC, iv) decrypted = unpad( cipher.decrypt(base64.b64decode(ciphertext)), AES.block_size ) return decrypted.decode() plaintext = "This is a secret message!" result = aes_encrypt(plaintext) print(f"Original: {plaintext}") print(f"Encrypted: {result['ciphertext']}") print(f"Key: {result['key']}") print(f"IV: {result['iv']}") decrypted = aes_decrypt( result['ciphertext'], result['key'], result['iv'] ) print(f"Decrypted: {decrypted}") ``` ```python import subprocess def a ...[truncated 3191 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace AES-CBC with an authenticated-encryption construction such as AES-GCM or ChaCha20-Poly1305. 2. Generate a unique random nonce for every encryption operation and store only the nonce, ciphertext, authentication tag, salt, and non-secret algorithm parameters with the encrypted data. 3. Never print or return raw encryption keys by default. 4. If key export is explicitly requested, use a distinct, clearly identified secure-export workflow and warn that anyone possessing the key can decrypt the data. 5. Derive keys from passwords using Argon2id, scrypt, or PBKDF2 with a random salt and appropriate work factors. 6. Do not pass passwords through command-line arguments. Supply them through a protected file descriptor, restricted temporary file, or dedicated secret-input mechanism. 7. Avoid printing original or decrypted plaintext unless explicitly requested. 8. Handle decryption and authentication errors uniformly to reduce padding-oracle and diagnostic side channels. 9. Redact keys, passwords, and plaintext from application and agent logs. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:707
Finding
Mnemonic Generator Is Predictable and Does Not Implement BIP39<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:707-731` **Vulnerability Type**: Insecure cryptographic random generation and misleading BIP39 implementation **Risk Level**: Medium ### Vulnerable Code ```python # Generate BIP39 mnemonic (requires mnemonic library) import os import hashlib # Simple 12-word mnemonic generator (simplified) words = [ "abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd", "abuse", "access", "accident", "account", "accuse", "achieve", "acid" # ... full wordlist would be 2048 words ] # Generate random entropy entropy = os.urandom(16) entropy_hash = hashlib.sha256(entropy).digest() # For demo, just show random selection import random mnemonic = ' '.join(random.choice(words) for _ in range(12)) print("Mnemonic (demo):", mnemonic) print("Note: Use proper BIP39 library for production") ``` ### Technical Analysis The section is presented as a BIP39 mnemonic generator, but it does not implement BIP39. The cryptographically secure entropy generated with `os.urandom` is never used in word selection, and `entropy_hash` is also unused. Words are instead selected using Python's general-purpose `random` module, which is not intended for cryptographic secret generation. Selection is limited to 16 words rather than the standardized 2,048-word BIP39 list, and the implementation does not encode entropy and checksum bits according to the BIP39 specification. The warning identifies the implementation as a demo, but users can still copy and run the code from a section advertised as BIP39 generation. A 12-word output selected from 16 entries has a maximum combinatorial space of approximately 48 bits before accounting for the predictability of the non-cryptographic PRNG. It may also be rejected by compliant BIP39 software because it lacks a valid checksum. ### Attack Path 1. A user requests or runs the advertised BIP39 mnemonic generator. 2. The example selects 12 words from a li ...[truncated 898 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the simplified generator from the Skill, or rename it so it cannot be mistaken for BIP39. 2. Use a reviewed BIP39 implementation with the complete standardized 2,048-word list. 3. Generate entropy exclusively through a cryptographically secure random-number generator. 4. Implement the required entropy-to-checksum-to-word-index mapping through a maintained library rather than custom code. 5. Validate generated phrases with an independent BIP39 checksum implementation. 6. State directly beside the output that demonstration phrases must never be used for wallets, credentials, or production keys. 7. Avoid printing real recovery phrases into agent logs. Prefer a secure local interface designed to prevent persistence or unintended disclosure. ]]>
Vulnerability Patterns
  • 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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (10)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
## 17. Unix Permissions | Unix 权限工具

### Chmod Calculator | Chmod 计算器

**English:**
```bash
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Credential Access

High
Category
Privilege Escalation
Content
import json

def env_to_dict(env_string):
    """Convert .env format to dict"""
    result = {}
    for line in env_string.strip().split('\n'):
        line = line.strip()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
import json

def env_to_dict(env_string):
    """Convert .env format to dict"""
    result = {}
    for line in env_string.strip().split('\n'):
        line = line.strip()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The network tools encourage use of external services like ifconfig.me, ipinfo.io, ip-api.com, GitHub, and httpbin without warning that user data, IP address, headers, tokens, or request bodies may be sent off-device. In an agent setting, this omission can lead to unintentional data disclosure and privacy violations.

External Transmission

Medium
Category
Data Exfiltration
Content
**English:**
```bash
# GET request
curl -s https://api.github.com

# POST request
curl -X POST -H "Content-Type: application/json" -d '{"name":"test"}' https://httpbin.org/post
Confidence
94% confidence
Finding
The HTTP request test examples explicitly transmit data to external endpoints, including POST bodies and authorization headers. If adapted by an agent with real user inputs, these examples could leak sensitive information or perform unintended outbound actions.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The QR code generator goes beyond local data transformation by invoking system binaries and automatically installing missing software with Homebrew. In an agent context, auto-install behavior can modify the host environment unexpectedly and may be abused to trigger unauthorized package installation or command execution.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The QR reader similarly auto-installs external software and then executes it, which expands the skill from parsing data into changing the local system state. This creates unnecessary risk in agent environments where package manager execution can have security and supply-chain implications.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The ASCII art generator includes automatic installation of figlet through Homebrew, which is unrelated to the core transformation task and changes the system environment. Such behavior is risky because a simple text-formatting request should not trigger package installation or arbitrary subprocess execution.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
result = chmod_calculator(user_r=True, user_w=True, user_x=True,
                          group_r=True, group_x=True,
                          other_r=True)
print(f"chmod 755 = {result}")  # 755

# Decode permissions
print("\n=== Decode chmod values ===")
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger list is extremely broad and contains many common phrases, increasing the chance the skill activates in contexts the user did not intend. Over-broad activation is dangerous because it can expose powerful network and system-command features during unrelated conversations.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
SKILL.md:1964