Back to skill

Security audit

Funnel Analyzer

Security checks for vulnerabilities and agentic risk

Overview

The skill includes a real funnel analyzer, but it also ships an unrelated persistent utility and has an input-validation flaw that can run commands from crafted funnel data.

Review before installing. Use only with trusted funnel data unless the arithmetic parsing is fixed to accept canonical integers only, and remove or clearly document the generic script.sh storage behavior. I did not find network exfiltration, remote code loading, destructive commands, or startup persistence.

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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/funnel.sh:53
Finding

Arbitrary Command Execution Through Unvalidated Bash Arithmetic Expressions

Content
View full analysis
0 )); then bar_width=$((val * max_width / first_val)) fi ``` The same pattern appears in the diagnostic and optimization functions: ```bash local val="${pair##*:}" ... local conv_rate=$((val * 100 / prev_val)) local drop=$((prev_val - val)) local drop_rate=$((drop * 100 / prev_val)) ``` ```bash local val="${pair##*:}" if (( idx > 0 )); then local drop_rate=$(( (prev_val - val) * 100 / prev_val )) ``` Comparison values are also evaluated without validation: ```bash local vA="${valsA[$i]}" local vB="${valsB[$i]}" if (( i == 0 )); then printf "| 步骤%d | %s | %s | - | - |\n" "$((i+1))" "$vA" "$vB" else local rateA=$((vA * 100 / prevA)) local rateB=$((vB * 100 / prevB)) ``` ### Technical Analysis Bash arithmetic contexts such as `$((...))` and `((...))` do not merely convert strings to integers. Variable values can be recursively interpreted as arithmetic expressions. In particular, crafted array-subscript expressions can contain command substitutions that Bash executes while resolving the arithmetic expression. The script extracts count values directly from command-line input and passes them into arithmetic contexts without first requiring a canonical integer representation. Quoting the original command-line argument does not prevent this secondary evaluation inside Bash arithmetic syntax. All commands that process supplied funnel counts are affected: - ...[truncated 1428 chars]
Remediation
View remediation
&2 return 1 fi if (( 10#$value > 1000000000 )); then printf 'Count exceeds the supported limit: %s\n' "$value" >&2 return 1 fi } ``` Apply validation to every parsed value: ```bash local val="${pair##*:}" validate_count "$val" || return 1 val=$((10#$val)) ``` Use `10#` only after the regular-expression check to force base-10 interpretation and avoid octal handling of leading zeroes. Apply the same validation independently to every member of `valsA` and `valsB`. Additional hardening should include: 1. Reject empty values, signs, whitespace, variable names, array syntax, and arithmetic operators. 2. Impose a reasonable upper bound to prevent integer overflow and excessive output generation. 3. Centralize parsing in one function rather than duplicating unsafe parsing in each command. 4. Add regression tests using command substitutions, array subscripts, malformed counts, negative numbers, and oversized integers. 5. Ensure invalid input produces a controlled error before any arithmetic expression is evaluated. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/funnel.sh:103
Finding

Division by Zero in Funnel Calculations Causes Process Termination

Content
View full analysis
0 )); then local drop_rate=$(( (prev_val - val) * 100 / prev_val )) ``` The comparison command divides by both previous and initial values: ```bash local rateA=$((vA * 100 / prevA)) local rateB=$((vB * 100 / prevB)) ``` ```bash local totalA=$((prevA * 100 / ${valsA[0]})) local totalB=$((prevB * 100 / ${valsB[0]})) ``` ### Technical Analysis A funnel can contain an initial or intermediate count of zero. The script does not consistently reject that condition or define how an undefined conversion rate should be represented. When a zero value becomes `first_val`, `prev_val`, `prevA`, `prevB`, or the first comparison-array element, a later arithmetic division raises a Bash division-by-zero error. Because the script enables `set -e`, the affected operation terminates instead of returning a controlled report or validation message. ### Attack Path 1. A user or attacker supplies a funnel containing zero as the initial or an intermediate count. 2. The parser accepts zero as a count. 3. Processing reaches a later funnel stage. 4. The script uses the zero count as a denominator. 5. Bash raises an arithmetic error and terminates report generation. Representative triggering inputs include: ```bash bash scripts/funnel.sh create test 'start:0,end:1' ...[truncated 721 chars]
Remediation
View remediation
&2 return 1 fi ``` If zero-count stages are legitimate, display an undefined result instead of dividing: ```bash if (( prev_val > 0 )); then conv_rate=$((val * 100 / prev_val)) else conv_rate="N/A" fi ``` Apply the check at every division site, including: - Final conversion in `cmd_create`. - Step conversion and drop rate in `cmd_diagnose`. - Drop rate in `cmd_optimize`. - Step and total conversions in `cmd_compare`. Also validate that every funnel contains the minimum required number of stages and add tests for initial zeroes, intermediate zeroes, all-zero funnels, and empty comparison arrays. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/script.sh:5
Finding

Undisclosed Plaintext Persistence of User-Supplied Command Arguments

Content
View full analysis
> "$DATA_DIR/history.log"; } ``` Multiple handlers forward the first user-supplied argument to that log: ```bash cmd_run() { echo " Running: $1" _log "run" "${1:-}" } cmd_config() { echo " Config: $DATA_DIR/config.json" _log "config" "${1:-}" } cmd_add() { echo "$(date +%Y-%m-%d) $*" >> "$DB"; echo " Added: $*" _log "add" "${1:-}" } cmd_search() { grep -i "$1" "$DB" 2>/dev/null || echo " Not found: $1" _log "search" "${1:-}" } ``` ### Technical Analysis The generic utility persistently records command names and first arguments in a predictable plaintext file under the user's data directory. The `add` command additionally stores all arguments in `data.log`. No restrictive `umask` or explicit file permissions are established. Actual visibility therefore depends on the invoking environment's default umask and directory permissions. The skill documentation does not explain that command arguments are retained, and this generic logging behavior is not necessary for the documented funnel-analysis functionality. If users provide business metrics, search terms, identifiers, tokens, or other sensitive values as arguments, those values may remain on disk beyond the current session. ### Attack Path 1. A user invokes `scripts/script.sh` with sensitive information in an argument. 2. The relevant handler passes the first argume ...[truncated 992 chars]
Remediation
View remediation
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
99% confidence
Finding

The declared description promises a specialized funnel analysis capability, including conversion funnel creation, diagnostics, benchmarks, optimization recommendations, reporting, and funnel comparison. The supplied code does none of that. Instead, it is a simple multi-purpose command-line tool that manages local text data files and command history under a user data directory. Its primary behavior is generic CRUD-like logging and retrieval, not analytics. This is a material purpose mismatch rather than a minor implementation difference.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script's actual behavior is a generic local note/log manager with commands like add, list, search, and export, not a funnel analysis tool as declared in the metadata. This mismatch is dangerous because users or higher-level agents may grant or invoke the skill under false assumptions, causing unintended access to local data paths, persistence of user-supplied content, and deceptive capability masking that can hide future abuse.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The description and usage sections are primarily written in Chinese, while the file does not state that the skill is China-specific or offer users a language/locale choice. This can violate language/locale policy when users are implicitly forced into a specific language without opt-in.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The command list includes very vague or opaque triggers such as 1, 2, 3, and generic labels like content or app without explaining inputs, outputs, side effects, or safety boundaries. Ambiguous commands increase the risk of user confusion, accidental invocation of unintended behavior, and make security review harder because operators cannot tell what each trigger will do.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script’s user-facing help and operational output are primarily in Chinese, including command descriptions, examples, and status messages. Because this is a general-purpose funnel analysis tool and the file does not offer any language selection or explain a justified locale restriction, it creates a natural-language policy concern under the language/locale rule.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The inline help and comments explicitly describe the program as a 'Multi-purpose utility tool', which directly contradicts the stated funnel-analysis skill intent. This inconsistency increases supply-chain and trust risk because it signals the packaged code may have been repurposed, mislabeled, or insufficiently reviewed, making it easier for unsafe functionality to be hidden behind benign-looking metadata.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown file presents all substantive guidance in Chinese, and there is no indication that the user can choose another language or that the skill is intentionally limited to a Chinese-speaking audience. Under the language/locale policy check, forcing a single language without opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.