Back to skill

Security audit

Meme Generator

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly stays local, but its advertised meme purpose does not fully match the bundled scripts and one script keeps user-provided command text in local log files without clear disclosure.

Review before installing. Avoid passing secrets, private project names, or sensitive search terms to this skill because one bundled script can retain command text on disk. Expect only simple local meme text/template output, and be aware that the package includes mismatched utility behavior and unavoidable publisher branding in script output.

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

other

Note
Location
scripts/meme.sh:39
Finding
Unconditional Third-Party Promotional Output Injection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/meme.sh:39` **Vulnerability Type**: Unwanted output injection **Risk Level**: Low ### Vulnerable Code ```bash print("\nPowered by BytesAgain | bytesagain.com") ``` ### Technical Analysis The script unconditionally appends third-party branding and a domain name to every result, regardless of the command being executed. This output is unrelated to the requested meme-generation operation and cannot be disabled by the caller. If an AI agent invokes the script and relays its output without additional filtering, the promotional content becomes part of the agent's response. This does not modify the agent's instructions, safety constraints, or privileges, so it does not meet the definition of skill instruction hijacking. It is instead categorized as unwanted promotional output injection. The same brand and external domain also appear in `SKILL.md`, but no network request to that domain was identified. ### Attack Path 1. A user asks an agent to generate meme content. 2. The agent invokes `scripts/meme.sh`. 3. The script performs the requested local operation. 4. The script unconditionally appends `Powered by BytesAgain | bytesagain.com`. 5. The agent may relay the contaminated output to the user as if it were an essential part of the result. ### Impact Assessment No system privileges, credentials, or additional access can be obtained through this behavior. The scope is limited to output integrity, unrequested advertising, and potential user redirection to an external website. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the unconditional promotional output from normal command results. - Keep project attribution in package metadata or documentation instead of generated content. - If attribution must be available at runtime, expose it through an explicit `about` or `version` command. - Ensure operational output contains only content relevant to the command requested by the user. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/script.sh:32
Finding
Undisclosed Persistent Logging of User-Supplied Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/script.sh:32` **Vulnerability Type**: Plaintext storage of potentially sensitive user input **Risk Level**: Medium ### Vulnerable Code ```bash _log() { echo "$(date '+%m-%d %H:%M') $1: $2" >> "$DATA_DIR/history.log"; } ``` The logging function is called by multiple commands, including: ```bash _log "run" "${1:-}" _log "config" "${1:-}" _log "status" "${1:-}" _log "init" "${1:-}" _log "list" "${1:-}" _log "add" "${1:-}" _log "remove" "${1:-}" _log "search" "${1:-}" _log "export" "${1:-}" _log "info" "${1:-}" ``` ### Technical Analysis Command arguments are appended in plaintext to the persistent file `$DATA_DIR/history.log`. The documentation does not clearly disclose that command input will be retained. The script does not establish a restrictive file-creation mask before creating the data directory and log file. Consequently, effective permissions depend on the invoking user's ambient `umask`. In an environment with permissive defaults or a shared data directory, other local users or processes may be able to read retained input. Only the first command argument is logged, which limits the amount captured but does not eliminate the risk. Search terms, meme topics, labels, or other sensitive text supplied as the first argument can remain on disk after the command completes. ### Attack Path 1. A user invokes a supported command with sensitive content as its first argument, for example: ```bash meme-generator search "confidential-project-name" ``` 2. The corresponding command handler invokes `_log`. 3. `_log` appends the command name and first argument to `$DATA_DIR/history.log`. 4. The information persists after the interaction ends. 5. A later process or local user with access to the data directory reads the log file and recovers the retained input. ### Impact Assessment The script runs with the invoking user's privileges and does not escalate privileges. Exposure is limited to a ...[truncated 384 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not log user-supplied arguments by default. - If operational logging is necessary, log only command names and non-sensitive metadata. - Clearly disclose what information is retained, where it is stored, and for how long. - Establish restrictive permissions before creating storage: ```bash umask 077 mkdir -p -- "$DATA_DIR" ``` - Explicitly create or validate the log file with owner-only permissions: ```bash touch -- "$DATA_DIR/history.log" chmod 600 -- "$DATA_DIR/history.log" ``` - Validate that a user-configured `MEME_GENERATOR_DIR` is not an unsafe shared directory or symbolic-link target. - Provide commands to inspect, disable, rotate, and securely delete retained history. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/meme.sh:40
Finding
Unquoted Input Expansion Causes Word Splitting and Pathname Disclosure<![CDATA[ ## Vulnerability Details **File Location**: `scripts/meme.sh:3,40` **Vulnerability Type**: Unsafe shell argument expansion **Risk Level**: Low ### Vulnerable Code ```bash CMD="${1:-help}"; shift 2>/dev/null || true; INPUT="$*" ``` The collected value is later expanded without quotes: ```bash ' "$CMD" $INPUT ``` ### Technical Analysis The script first combines all remaining command arguments into the scalar variable `INPUT`. It then expands `$INPUT` without quotation marks when invoking Python. Unquoted shell expansion triggers: 1. Word splitting according to the current `IFS`. 2. Pathname expansion for wildcard characters such as `*`, `?`, and bracket expressions. As a result, input boundaries are not preserved. A literal wildcard supplied by a user can be expanded into filenames from the script's current working directory before Python receives the arguments. This construction does not, by itself, re-evaluate command substitutions embedded in the variable, so it is not direct arbitrary command execution. The confirmed risks are argument corruption and disclosure of matching pathnames through generated output. ### Attack Path 1. A user supplies a quoted wildcard as meme input: ```bash ./scripts/meme.sh generate '*' ``` 2. Line 3 stores the literal `*` in `INPUT`. 3. Line 40 expands `$INPUT` without quotes. 4. The shell performs pathname expansion and replaces `*` with matching filenames in the current working directory. 5. Python joins those filenames into the topic. 6. The script prints the expanded filenames in its output, potentially exposing local directory structure to the caller. ### Impact Assessment No privilege escalation or arbitrary command execution was identified. The script remains limited to the invoking user's access rights. The primary impact is disclosure of names of non-hidden files and directories in the current working directory. Word splitting can also alter user input and cause incorrect or misleading ou ...[truncated 58 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Preserve the original arguments as an array and pass each argument to Python without word splitting or pathname expansion: ```bash CMD="${1:-help}" if (($# > 0)); then shift fi python3 -c ' # Python code ' "$CMD" "$@" ``` Alternatively, if the Python program should receive the complete input as one argument, quote the scalar expansion: ```bash python3 -c ' # Python code ' "$CMD" "$INPUT" ``` Using `"$@"` is preferable because it preserves the caller's original argument boundaries. ShellCheck should also be added to automated checks; it identifies this pattern as an unsafe unquoted expansion. ]]>
Vulnerability Patterns
  • 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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
The markdown explicitly states the tool is 'designed for Chinese users,' which imposes a locale-specific positioning without any user opt-in or alternative language choice. Under the policy, locale constraints should either be optional for the user or clearly justified as region-specific; neither is provided here.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The header comment at L002 and help text at L011-L027 present the tool as 'meme-generator', which implies meme creation functionality. However, the implemented commands only print status/config info, append arbitrary text to a local log file, search/list/export entries, and write command history; no code performs meme generation or image/text rendering.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The script persistently records command arguments into history and data files under the user’s home directory without clear warning or consent. If users pass secrets, personal data, or sensitive search terms as arguments, those values can remain on disk and be exposed to other local processes, backups, or later disclosure.

Static analysis

No suspicious patterns detected.