Back to skill

Security audit

Story

Security checks for vulnerabilities and agentic risk

Overview

This skill is a local story/content logging CLI with disclosed local storage, but it does not actually perform the creative transformations its command names imply.

Install only if you want a local plaintext logger for story and marketing-related entries, not an actual AI editor, translator, optimizer, or post scheduler. Do not store sensitive or proprietary drafts unless you are comfortable with them being kept under ~/.local/share/story and export CSV/JSON carefully when entries may contain untrusted text.

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

Note
Location
scripts/script.sh:108
Finding

Search Argument Option Injection and Regular Expression Abuse

Content
View full analysis

Vulnerability Details

File Location: scripts/script.sh, lines 108-119
Vulnerability Type: Search option injection and uncontrolled regular expression
Risk Level: Low

Vulnerable Code

bash
_search() {
    local term="${1:?Usage: story search <term>}"
    echo "Searching for: $term"
    for f in "$DATA_DIR"/*.log; do
        [ -f "$f" ] || continue
        local m=$(grep -i "$term" "$f" 2>/dev/null || true)
        if [ -n "$m" ]; then
            echo "  --- $(basename "$f" .log) ---"
            echo "$m" | sed 's/^/    /'
        fi
    done
}

Technical Analysis

The attacker-controlled term is supplied directly to grep without an option terminator. If it begins with a hyphen, grep can interpret it as an option rather than as the intended search pattern. For example, an input such as --regexp=.* changes the effective expression and matches every log entry.

The search also treats input as a regular expression. A deliberately complex expression can consume excessive CPU when evaluated against large content logs. This is not shell command injection because the variable is quoted, but quoting does not prevent option injection or regular-expression abuse.

Attack Path

  1. An attacker supplies or persuades a user or automation process to pass a crafted value to story search.
  2. The command forwards the value to _search.
  3. grep -i "$term" "$f" interprets a leading-hyphen value as an additional command-line option.
  4. The attacker changes the matching behavior, potentially causing all locally stored story records to be emitted.
  5. Alternatively, a computationally expensive regular expression is repeatedly evaluated against every log file, potentially consuming CPU resources.

Impact Assessment

Exploitation occurs with the privileges of the user running the Skill and does not provide privilege escalation or arbitrary command execution. It can alt ...[truncated 281 chars]

Remediation
View remediation

Remediation Suggestions

Terminate option processing and use literal matching unless regular expressions are an intentional, documented feature:

bash
local m
m=$(grep -iF -- "$term" "$f" 2>/dev/null || true)

Additional hardening should include:

  • Limit the maximum length of search terms.
  • If regular-expression searches are required, expose them through a separate explicit mode.
  • Consider execution time or file-size limits when searching large or attacker-influenced logs.
  • Add tests for search terms beginning with -, including --regexp=.*, and terms containing regular-expression metacharacters.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/script.sh:54
Finding

Unescaped User Content in JSON, CSV, and Delimiter-Based Logs

Content
View full analysis

Vulnerability Details

File Location: scripts/script.sh, lines 54-91; representative input persistence at lines 126-143
Vulnerability Type: Structured-data injection, CSV formula injection, and log injection
Risk Level: Medium

Vulnerable Code

bash
_export() {
    local fmt="${1:-json}"
    local out="$DATA_DIR/export.$fmt"
    case "$fmt" in
        json)
            echo "[" > "$out"
            local first=1
            for f in "$DATA_DIR"/*.log; do
                [ -f "$f" ] || continue
                local name=$(basename "$f" .log)
                while IFS='|' read -r ts val; do
                    [ $first -eq 1 ] && first=0 || echo "," >> "$out"
                    printf '  {"type":"%s","time":"%s","value":"%s"}' "$name" "$ts" "$val" >> "$out"
                done < "$f"
            done
            echo "\n]" >> "$out"
            ;;
        csv)
            echo "type,time,value" > "$out"
            for f in "$DATA_DIR"/*.log; do
                [ -f "$f" ] || continue
                local name=$(basename "$f" .log)
                while IFS='|' read -r ts val; do echo "$name,$ts,$val" >> "$out"; done < "$f"
            done
            ;;
        txt)
            echo "=== Story Export ===" > "$out"
            for f in "$DATA_DIR"/*.log; do
                [ -f "$f" ] || continue
                echo "--- $(basename "$f" .log) ---" >> "$out"
                cat "$f" >> "$out"
            done
            ;;
        *) echo "Formats: json, csv, txt"; return 1 ;;
    esac
    echo "Exported to $out ($(wc -c < "$out") bytes)"
}

A representative content-writing branch persists arbitrary input without encoding:

bash
draft)
    shift
    if [ $# -eq 0 ]; then
        echo "Recent draft entries:"
        tail -20 "$DATA_DIR/draft.log" 2>/dev/null || echo "
...[truncated 3206 chars]
Remediation
View remediation

Remediation Suggestions

Apply encoding appropriate to every storage and export format:

  • Generate JSON with a dedicated JSON encoder such as jq, rather than interpolating strings manually.
  • Produce CSV using an implementation that applies RFC 4180 quoting: wrap fields in quotation marks and double every embedded quotation mark.
  • Neutralize spreadsheet-formula prefixes when CSV files are intended for interactive spreadsheet use. This policy should cover =, +, -, @, and leading control whitespace as appropriate for the target spreadsheet.
  • Replace the ad hoc pipe-delimited storage format with a robust structured format such as JSON Lines.
  • If the existing log format must be retained, reject or encode embedded newlines, carriage returns, and pipe characters before persistence.
  • Validate exported files with strict JSON and CSV parsers in automated tests.
  • Document whether exported content is safe for direct spreadsheet use and warn users when it is not.

A safer JSON implementation can construct each object with jq --arg, ensuring that quotation marks, backslashes, line breaks, and control characters are correctly escaped.

Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill advertises drafting, editing, optimization, and scheduling, but the documentation also reveals persistent local logging, history/statistics features, search/export capabilities, and additional content-processing commands not clearly disclosed in the declared purpose. This is dangerous because users may provide sensitive drafts or unpublished content without realizing it will be retained and made easier to enumerate, search, and export from local storage.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The description says to use the skill when 'drafting chapters, editing narratives, optimizing readability, scheduling posts,' which are broad, everyday content tasks rather than narrowly scoped trigger phrases. Because the file does not provide explicit trigger constraints or negative examples, this could cause unintended activation for many general writing requests.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script creates a persistent data directory and logs user content/activity to plaintext files under the user's home directory without any explicit disclosure, retention control, or consent mechanism. Because this skill handles free-form story drafts and edits, users may enter sensitive or proprietary content that can later be read by other local processes, users, backups, or support tooling.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The tool persistently records all user-provided text and exposes search, recent, status, and export workflows that make bulk retrieval trivial. In the context of a story-writing skill, this is more dangerous because drafts may include unpublished creative work, confidential client material, or personal data, and the plaintext export/search functions increase the chance of unintentional disclosure.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The help text and manifest describe a creative content tool, but every command implementation merely appends the provided text to local log files and prints it back later. There is no code that transforms content, improves readability, generates stories, or schedules posts beyond recording a text entry under a command-specific filename.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The statement at L017 says the skill works entirely offline and that data never leaves the machine. However, the same skill documentation includes internet-based homepage/source/feedback URLs (L006-L007, L098), which contradicts a strict offline-only claim at the documentation level. This is a documentation-level intent inconsistency rather than evidence of actual networking code execution.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The manifest scope is centered on creative stories: drafting chapters, editing narratives, optimizing readability, and scheduling posts. The extra commands broaden the tool into generic social/content marketing assistance, which is a semantic expansion beyond the declared story-focused purpose.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.