Back to skill

Security audit

Listenhub

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its media-generation purpose, but it needs Review because image setup can modify shell startup files, store an API key insecurely, and auto-install packages.

Install only if you are comfortable sending prompts, source text, URLs, and image-reference URLs to ListenHub/Marswave/Labnana APIs. Before using image generation, provide LISTENHUB_API_KEY yourself through your environment, install jq/curl manually, and avoid the first-run setup path that writes to shell rc files. Do not paste untrusted values as the API key or output directory, and do not upload private local reference images to public image hosts.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate-image.sh:350
Finding
Shell Startup-File Injection Through Unsanitized Configuration Values<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate-image.sh:350-393` **Vulnerability Type**: Persistent shell configuration injection **Risk Level**: High ### Vulnerable Code ```bash echo -n " Please paste your API key: " >&2 read -r api_key if [ -z "$api_key" ]; then echo "Error: API key cannot be empty" >&2 exit 1 fi # Check if config already exists (avoid duplicate append) if ! grep -q "^export LISTENHUB_API_KEY=" "$shell_rc" 2>/dev/null; then echo "export LISTENHUB_API_KEY=\"$api_key\"" >> "$shell_rc" else # If exists, replace sed_inplace "$shell_rc" "s|^export LISTENHUB_API_KEY=.*|export LISTENHUB_API_KEY=\"$api_key\"|" fi export LISTENHUB_API_KEY="$api_key" ``` ```bash echo -n " Image save location (default: ~/Downloads): " >&2 read -r output_dir # Default to ~/Downloads if [ -z "$output_dir" ]; then output_dir="$HOME/Downloads" fi # Expand ~ symbol output_dir="${output_dir/#\~/$HOME}" # Create directory if not exists mkdir -p "$output_dir" # Check if config already exists (avoid duplicate append) if ! grep -q "^export LISTENHUB_OUTPUT_DIR=" "$shell_rc" 2>/dev/null; then echo "export LISTENHUB_OUTPUT_DIR=\"$output_dir\"" >> "$shell_rc" else sed_inplace "$shell_rc" "s|^export LISTENHUB_OUTPUT_DIR=.*|export LISTENHUB_OUTPUT_DIR=\"$output_dir\"|" fi export LISTENHUB_OUTPUT_DIR="$output_dir" ``` ### Technical Analysis The script embeds user-controlled API-key and output-directory values directly into executable shell startup files such as `.zshrc`, `.bashrc`, or `.profile`. The values are placed inside double-quoted shell assignments without shell-safe encoding or validation. Shell expressions such as command substitutions and backticks remain active when the startup file is subsequently parsed. For example, a value containing `$(command)` can be written into an `export` statement and executed whenever a future shell sources that file. The replacement branch also interpolates the values directly into a `sed ...[truncated 1599 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not automatically modify executable shell startup files. Prefer an OS credential manager or a dedicated application configuration file. 2. Store non-secret settings in a file under a dedicated configuration directory, such as `${XDG_CONFIG_HOME:-$HOME/.config}/listenhub/config`. 3. Store API keys in an OS keychain or a dedicated file with mode `0600`. 4. If startup-file modification must remain available, require explicit user approval and display the exact destination and proposed change. 5. Validate API keys using the service's documented character set and expected prefix instead of accepting arbitrary shell syntax. 6. Validate output directories and reject newline, carriage-return, NUL, command-substitution, backtick, and shell-control characters. 7. Encode shell values using a shell-aware mechanism such as `printf '%q'` rather than direct interpolation. 8. Avoid interpolating untrusted data into `sed` expressions. Use a structured configuration format or safely escape all replacement and delimiter characters. 9. Write changes through a securely created temporary file, preserve permissions, and atomically replace the destination after validation. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate-image.sh:345
Finding
Plaintext API-Key Persistence Without Permission Enforcement<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate-image.sh:345-365` **Vulnerability Type**: Insecure storage of authentication credentials **Risk Level**: Medium ### Vulnerable Code ```bash if [ -z "${LISTENHUB_API_KEY:-}" ]; then echo "1. API Key" >&2 echo " Visit https://listenhub.ai/settings/api-keys" >&2 echo " (Requires subscription)" >&2 echo "" >&2 echo -n " Please paste your API key: " >&2 read -r api_key if [ -z "$api_key" ]; then echo "Error: API key cannot be empty" >&2 exit 1 fi # Check if config already exists (avoid duplicate append) if ! grep -q "^export LISTENHUB_API_KEY=" "$shell_rc" 2>/dev/null; then echo "export LISTENHUB_API_KEY=\"$api_key\"" >> "$shell_rc" else # If exists, replace sed_inplace "$shell_rc" "s|^export LISTENHUB_API_KEY=.*|export LISTENHUB_API_KEY=\"$api_key\"|" fi export LISTENHUB_API_KEY="$api_key" echo "" >&2 fi ``` ### Technical Analysis The script permanently stores the ListenHub API bearer token as plaintext in a general-purpose shell startup file. It does not inspect or enforce the permissions of that file before or after writing the credential. If the startup file does not already exist, shell redirection creates it according to the process umask. A permissive umask can result in credentials being readable by other local accounts. Existing startup files may also already have overly broad permissions. General-purpose shell files are commonly read by backup software, diagnostics, support tools, development utilities, and scripts. This gives the API key a wider exposure surface than a dedicated secrets store. The interactive input also uses `read -r` rather than silent input, so the key may be visible while it is entered. ### Attack Path 1. A user performs first-time image-generation setup. 2. The user enters a valid ListenHub API key. 3. The script writes the key into a shell startup file without enforcing restrictive permissions. 4. An ...[truncated 631 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store the API key in the operating system's credential manager, such as macOS Keychain, Windows Credential Manager, or a Linux secret service. 2. If file-based storage is unavoidable, use a dedicated secrets file rather than `.zshrc`, `.bashrc`, or `.profile`. 3. Create the secrets directory with mode `0700` and the key file with mode `0600`. 4. Set a restrictive umask, such as `umask 077`, before creating any credential file. 5. Verify ownership and permissions before loading an existing secrets file; reject files owned by another user or writable by a group or others. 6. Use silent input, such as `read -r -s`, when accepting the API key interactively. 7. Support environment-only operation so users and automated systems can provide the key without persistent storage. 8. Document key revocation and rotation procedures in case local exposure is suspected. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/generate-image.sh:245
Finding
Automatic Privileged Package Installation Without Explicit Approval<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate-image.sh:245-323` **Vulnerability Type**: Unexpected privileged system modification **Risk Level**: Medium ### Vulnerable Code ```bash check_dependencies() { local missing_deps=() local install_cmd="" # Check jq if ! command -v jq &>/dev/null; then missing_deps+=("jq") fi # Check curl if ! find_curl &>/dev/null; then missing_deps+=("curl") fi # If missing dependencies, auto-install if [ ${#missing_deps[@]} -gt 0 ]; then echo "→ Missing required tools: ${missing_deps[*]}" >&2 echo " Auto-installing..." >&2 echo "" >&2 case "$PLATFORM" in macos) install_cmd="brew install ${missing_deps[*]}" if ! command -v brew &>/dev/null; then echo "Error: Homebrew not detected" >&2 echo " Please install Homebrew first: https://brew.sh" >&2 echo " Or install manually: ${missing_deps[*]}" >&2 exit 1 fi ;; linux) # Detect Linux distribution if command -v apt-get &>/dev/null; then install_cmd="sudo apt-get update && sudo apt-get install -y ${missing_deps[*]}" elif command -v yum &>/dev/null; then install_cmd="sudo yum install -y ${missing_deps[*]}" elif command -v dnf &>/dev/null; then install_cmd="sudo dnf install -y ${missing_deps[*]}" elif command -v pacman &>/dev/null; then install_cmd="sudo pacman -S --noconfirm ${missing_deps[*]}" else echo "Error: No supported package manager detected" >&2 echo " Please install manually: ${missing_deps[*]}" >&2 exit 1 fi ;; windows) if command -v choco &>/dev/null; then install_cmd="choco install -y ${missing_deps[*]}" elif command -v scoop &>/dev/null; then install_cmd="scoop install ${missing_deps[*]}" else echo "Error: Chocolatey or Scoop not ...[truncated 2861 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic dependency installation from the generation script. 2. If a dependency is missing, terminate safely and print platform-specific installation instructions. 3. If installation assistance is retained, display the exact command and require explicit, interactive user confirmation before execution. 4. Never invoke `sudo` implicitly on behalf of the user or Agent. 5. Replace `eval` with direct command invocation using fixed argument arrays. 6. Separate setup functionality from normal image generation so routine execution cannot unexpectedly modify the system. 7. Allow operators to disable installation behavior through a secure-by-default policy, with automatic installation disabled by default. 8. Document all dependencies before invocation so users can provision them through their normal package-management and security-review processes. ]]>
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 (44)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Reading shell rc files for credentials and contacting GitHub for version checks are materially different from simple media generation, because they access local configuration and transmit network metadata to third parties. These behaviors expand the trust boundary and can expose secrets, browsing context, or environment details if users do not expect them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
Reading shell rc files for credentials and contacting GitHub for version checks are materially different from simple media generation, because they access local configuration and transmit network metadata to third parties. These behaviors expand the trust boundary and can expose secrets, browsing context, or environment details if users do not expect them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
Reading shell rc files for credentials and contacting GitHub for version checks are materially different from simple media generation, because they access local configuration and transmit network metadata to third parties. These behaviors expand the trust boundary and can expose secrets, browsing context, or environment details if users do not expect them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
Reading shell rc files for credentials and contacting GitHub for version checks are materially different from simple media generation, because they access local configuration and transmit network metadata to third parties. These behaviors expand the trust boundary and can expose secrets, browsing context, or environment details if users do not expect them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
Reading shell rc files for credentials and contacting GitHub for version checks are materially different from simple media generation, because they access local configuration and transmit network metadata to third parties. These behaviors expand the trust boundary and can expose secrets, browsing context, or environment details if users do not expect them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
Reading shell rc files for credentials and contacting GitHub for version checks are materially different from simple media generation, because they access local configuration and transmit network metadata to third parties. These behaviors expand the trust boundary and can expose secrets, browsing context, or environment details if users do not expect them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
Reading shell rc files for credentials and contacting GitHub for version checks are materially different from simple media generation, because they access local configuration and transmit network metadata to third parties. These behaviors expand the trust boundary and can expose secrets, browsing context, or environment details if users do not expect them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Reading shell rc files for credentials and contacting GitHub for version checks are materially different from simple media generation, because they access local configuration and transmit network metadata to third parties. These behaviors expand the trust boundary and can expose secrets, browsing context, or environment details if users do not expect them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
Reading shell rc files for credentials and contacting GitHub for version checks are materially different from simple media generation, because they access local configuration and transmit network metadata to third parties. These behaviors expand the trust boundary and can expose secrets, browsing context, or environment details if users do not expect them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
Reading shell rc files for credentials and contacting GitHub for version checks are materially different from simple media generation, because they access local configuration and transmit network metadata to third parties. These behaviors expand the trust boundary and can expose secrets, browsing context, or environment details if users do not expect them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
Reading shell rc files for credentials and contacting GitHub for version checks are materially different from simple media generation, because they access local configuration and transmit network metadata to third parties. These behaviors expand the trust boundary and can expose secrets, browsing context, or environment details if users do not expect them.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The script automatically installs missing dependencies by constructing package-manager commands and executing them with eval, including sudo on Linux and non-interactive flags on some platforms. That behavior exceeds the expected scope of a media-generation skill and can trigger privileged system changes without explicit user approval, creating unnecessary supply-chain and privilege-escalation risk.

Chaining Abuse

High
Category
Tool Misuse
Content
linux)
        # Detect Linux distribution
        if command -v apt-get &>/dev/null; then
          install_cmd="sudo apt-get update && sudo apt-get install -y ${missing_deps[*]}"
        elif command -v yum &>/dev/null; then
          install_cmd="sudo yum install -y ${missing_deps[*]}"
        elif command -v dnf &>/dev/null; then
Confidence
94% confidence
Finding
The apt-get path chains update and install in one eval-executed command, increasing the amount of change performed in a single automated step and reducing user visibility into what will happen. Chained privileged operations are riskier because they combine repository refresh and package installation without an intervening review point.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
elif command -v dnf &>/dev/null; then
          install_cmd="sudo dnf install -y ${missing_deps[*]}"
        elif command -v pacman &>/dev/null; then
          install_cmd="sudo pacman -S --noconfirm ${missing_deps[*]}"
        else
          echo "Error: No supported package manager detected" >&2
          echo "  Please install manually: ${missing_deps[*]}" >&2
Confidence
94% confidence
Finding
The --noconfirm flag suppresses package-manager prompts and weakens a key safety control that would otherwise force user review. Combined with automatic install logic, it enables broad system modification with less friction than users would expect from a media skill.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The skill’s declared purpose is image generation, but the script persistently modifies user shell startup files to store API keys and output-path settings. Persistent mutation of login shell configuration is a sensitive side effect that can leak secrets, break user environments, or establish unwanted long-lived behavior unrelated to the immediate media task.

Missing User Warnings

High
Confidence
99% confidence
Finding
The script asks for the API key and silently persists it into a shell startup file in plaintext. Storing credentials in broadly sourced shell RC files without a prominent warning or safer secret-storage mechanism increases the risk of accidental disclosure, backup leakage, and unintended propagation across sessions.

Credential Access

High
Category
Privilege Escalation
Content
Error: LISTENHUB_API_KEY not set

Setup:
  1. Get API key from https://listenhub.ai/settings/api-keys
  2. Add to ~/.zshrc or ~/.bashrc:
     export LISTENHUB_API_KEY="lh_sk_..."
  3. Run: source ~/.zshrc
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill explicitly instructs the agent to use shell scripts and make networked API calls, but it does not declare any tool scope such as allowed-tools or permissions. This creates a governance gap: a host may permit broader shell/network access than the skill actually needs, increasing the blast radius if the skill is invoked or if its instructions are abused.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The skill uses broad trigger phrases like 'explain anything' and common user intents such as 'read this aloud' or 'generate an image.' Overly broad activation criteria increase the chance the skill is invoked in contexts where users did not intend to send content to an external API, which can lead to accidental disclosure of sensitive text, URLs, or files.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The skill instructs the agent to upload local reference images to third-party hosting services before generation. This is a clear external data exfiltration path: local files may contain sensitive content or metadata, and sending them to unrelated third parties materially increases privacy and compliance risk beyond the core service's stated purpose.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- The user provides only a short topic or phrase (e.g., "a cat"), AND
- The user has not explicitly stated they want verbatim generation

In this case, ask whether the user would like help enriching the prompt. Do not optimize without confirmation.

**When to never modify**:
- The user pastes a long, structured, or detailed prompt — treat them as experienced
Confidence
75% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The natural-language behavior is restricted to two languages by validation logic, which effectively forces a locale/language policy. The file does not explain why the restriction exists or present it as a documented, justified limitation for a region-specific or service-specific tool.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This shell script posts the assembled request body to an external API endpoint, and the payload can include the user's query, source URLs, and source text. Although the file comments describe usage, they do not explicitly warn that this content will be transmitted to a remote service.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script forwards arbitrary user-provided script content to an external ListenHub API via api_post without any explicit warning, consent prompt, or indication that the text will leave the local environment. This creates a real privacy and data-handling risk because users may supply sensitive text, believing the tool is only performing a local transformation.

External Transmission

Medium
Category
Data Exfiltration
Content
fi

# Configuration
API_ENDPOINT="https://api.labnana.com/openapi/v1/images/generation"
AGENT_SKILLS_CLIENT_ID="PJBkELS1o_q9nJ~NzF2_Fmr21TNX&~eoJR49FFdFhD3U"
MAX_RETRIES=3
INITIAL_TIMEOUT=600
Confidence
95% confidence
Finding
The hardcoded API endpoint indicates that the script sends data to a third-party remote service. In this skill context that is functionally necessary, but it still creates an external data-exposure boundary and should be treated as a real transmission risk, especially when prompts or reference URLs may be sensitive.

Static analysis

No suspicious patterns detected.