Back to skill

Security audit

Fortune Teller

Security checks for vulnerabilities and agentic risk

Overview

The skill presents itself as a fortune-telling tool, but it also bundles a mismatched local utility that can silently store user-supplied text and command history on disk.

Review this before installing if you expect only entertainment fortune-telling. Avoid entering sensitive personal data into add/search/run commands, because the bundled utility may keep plaintext logs under the configured fortune-teller data directory. Expect some Chinese output and inconsistent command availability.

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/script.sh:5
Finding

Undisclosed Plaintext Persistence of User-Supplied Arguments

Content
View full analysis

Vulnerability Details

File Location: scripts/script.sh:5-7, 34, 52-55
Vulnerability Type: Undisclosed plaintext data storage and activity logging
Risk Level: Medium

Vulnerable Code

bash
DATA_DIR="${FORTUNE_TELLER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/fortune-teller}"
DB="$DATA_DIR/data.log"
mkdir -p "$DATA_DIR"

_log() { echo "$(date '+%m-%d %H:%M') $1: $2" >> "$DATA_DIR/history.log"; }

cmd_add() {
    echo "$(date +%Y-%m-%d) $*" >> "$DB"; echo "  Added: $*"
    _log "add" "${1:-}"
}

Technical Analysis

The script persistently stores arbitrary arguments supplied to the add command in data.log. It also records command activity and the first argument in history.log. The logging occurs automatically and is not clearly disclosed by the skill documentation.

Both files are plaintext, and the script does not establish a restrictive creation mask or explicitly set file permissions. Their effective permissions therefore depend on the invoking process's environment and umask. If users provide personal, confidential, or otherwise sensitive text, that content remains on disk after execution.

This behavior is also outside the documented fortune-calculation functionality and unnecessarily increases the amount of retained user data.

Attack Path

  1. A user invokes the generic utility with sensitive content, for example through the add command.
  2. cmd_add appends the complete argument string to data.log.
  3. _log separately appends the first argument and command metadata to history.log.
  4. The content persists across sessions in the configured data directory.
  5. A local process or account that has permission to read those files can recover the retained content. The same content can also be exposed later through the script's list or export commands when invoked by an authorized user or process.

Impact Assessment

The issue can expose user-supplied informati ...[truncated 454 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove script.sh if the generic database and logging functionality is not required for the fortune-telling skill.

  • Do not log command arguments by default. Record only non-sensitive operational metadata when logging is necessary.

  • Clearly document all persistent storage, including the data collected, storage path, retention period, and deletion procedure.

  • Establish restrictive permissions before creating storage:

    bash
    umask 077
    mkdir -p -- "$DATA_DIR"
    
  • Create files with owner-only permissions and verify that the destination is an expected regular file before appending.

  • Provide an explicit opt-in mechanism for logging and a command that securely removes retained history.

  • Avoid accepting secrets, credentials, or other sensitive data through this utility.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/fortune.sh:2
Finding

Unsafe Interpretation of User-Controlled Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: scripts/fortune.sh:2-3, 51; scripts/script.sh:63-66
Vulnerability Type: Unquoted shell expansion and option injection
Risk Level: Low

Vulnerable Code

bash
CMD="${1:-help}"; shift 2>/dev/null || true; INPUT="$*"
python3 -c '
...
' "$CMD" $INPUT

The search function contains a separate option-injection condition:

bash
cmd_search() {
    grep -i "$1" "$DB" 2>/dev/null || echo "  Not found: $1"
    _log "search" "${1:-}"
}

Technical Analysis

Although INPUT is quoted when assigned, it is expanded without quotes when passed to Python:

bash
"$CMD" $INPUT

This causes the shell to apply word splitting and pathname expansion. Input containing wildcard characters can therefore expand to local pathnames, and whitespace cannot be preserved as originally supplied. This is not direct shell command injection because shell metacharacters introduced through parameter expansion are not reparsed as shell syntax, but it can alter the argument list and potentially generate a very large number of arguments.

The grep invocation passes the user-controlled search value without the -- end-of-options delimiter. A value beginning with - can be interpreted as a grep option instead of a literal search pattern, changing command behavior or causing errors.

Attack Path

  1. An attacker or untrusted caller supplies wildcard-based input to fortune.sh, such as an argument containing *.
  2. The unquoted $INPUT expansion is processed by the shell.
  3. Matching filenames in the current working directory are expanded into separate Python arguments.
  4. The fortune operation receives modified input; a directory containing many matching entries can also cause excessive argument expansion or an operating-system “argument list too long” failure.

For the search path:

  1. The caller supplies a search term beginning with a hyphen.
  2. `gr ...[truncated 632 chars]
Remediation
View remediation

Remediation Suggestions

  • Preserve the original argument boundaries by passing the shifted positional parameters directly:

    bash
    CMD="${1:-help}"
    shift 2>/dev/null || true
    
    python3 -c '
    # Python implementation
    ' "$CMD" "$@"
    
  • Remove the intermediate INPUT="$*" string unless combining all arguments is explicitly required.

  • If one combined input string is required, pass it as one quoted argument:

    bash
    INPUT="$*"
    python3 -c '...' "$CMD" "$INPUT"
    
  • Terminate grep option parsing before the user-controlled pattern:

    bash
    grep -i -- "$1" "$DB"
    
  • Validate argument counts and reject missing, malformed, or excessively long inputs with a clear error.

  • Add tests covering whitespace, wildcard characters, leading hyphens, empty arguments, Unicode input, and large argument lists.

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
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script prints all user-facing content in Chinese string literals, including command results and labels, with no indication that the user can opt into another language. This can violate language/locale policy because it forces a specific language across the skill's outputs without documented choice or justification.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The top comment names the tool 'fortune-teller', while the help text and command implementations provide only generic utility actions like add, list, search, export, and status over a local log file. This is not merely incomplete documentation; the stated intent suggests a fortune-related function that the code does not implement at all.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script persistently stores user-supplied data and command history under a predictable path in the user's home data directory without clearly warning users about retention, sensitivity, or location. In a skill/agent context, this can expose prompts, searches, or other potentially sensitive local activity to later disclosure through local access, backups, or accidental export.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.