Back to skill

Security audit

Insurance Advisor

Security checks for vulnerabilities and agentic risk

Overview

This skill needs review before installation because it ships both an insurance advisor and an under-disclosed finance logger, and one insurance command has a local command-execution input bug.

Only install after reviewing or fixing the shell scripts. Do not pass untrusted text into the term or calculation commands, and do not enter real ID numbers, bank details, diagnoses, policy numbers, or full medical records. Be aware that one bundled script can save finance or insurance notes locally in plaintext and export them from ~/.local/share/insurance-advisor.

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/insurance.sh:350
Finding
Arbitrary Command Execution Through Unvalidated Arithmetic Input<![CDATA[ ## Vulnerability Details **File Location**: `scripts/insurance.sh`, lines 350-377 **Vulnerability Type**: Arithmetic expression injection leading to local command execution **Risk Level**: High ### Vulnerable Code ```bash cmd_term() { local age="${1:?Usage: term <age> <coverage> <years>}" local coverage="${2:?Please provide coverage}" local years="${3:?Please provide coverage duration}" local age_factor premium if [ "$age" -lt 30 ]; then age_factor="0.8" elif [ "$age" -lt 40 ]; then age_factor="1.0" elif [ "$age" -lt 50 ]; then age_factor="1.5" else age_factor="2.5"; fi premium=$(echo "scale=0; $coverage * 0.0015 * $age_factor" | bc) local total total=$(echo "$premium * $years" | bc) cat <<EOF ... Coverage duration: ${years} years (until ${age}+${years}=$((age+years)) years old) Estimated annual premium: ¥$(printf "%'.0f" "$premium") Total payments: ¥$(printf "%'.0f" "$total") Leverage ratio: 1:$(echo "scale=0; $coverage / $total" | bc) ... EOF } ``` The displayed English labels reproduce the meaning of the original output text; the executable expressions are unchanged. ### Technical Analysis The `age`, `coverage`, and `years` arguments are accepted without validating that they contain only decimal integers. The user-controlled `years` value is subsequently referenced inside Bash arithmetic expansion: ```bash $((age+years)) ``` Bash arithmetic expressions can recursively interpret variable values as arithmetic syntax. Crafted expressions involving array subscripts and command substitutions can therefore cause shell commands to be evaluated while the arithmetic expression is resolved. Passing the value through `bc` earlier is not a security control. `bc` may report malformed input without sanitizing or replacing the original `years` variable, which is later passed directly into Bash arithmetic evaluation. The same general hardening requirement applies to all numeric arguments used in comparisons, `bc` expressi ...[truncated 1325 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Validate every numeric argument before it is used by `test`, `bc`, `printf`, or Bash arithmetic: ```bash require_positive_integer() { local name="$1" local value="$2" if [[ ! "$value" =~ ^[0-9]+$ ]] || (( 10#$value <= 0 )); then printf 'Error: %s must be a positive decimal integer.\n' "$name" >&2 exit 1 fi } require_positive_integer "age" "$age" require_positive_integer "coverage" "$coverage" require_positive_integer "years" "$years" ``` Additional hardening should include: 1. Enforce realistic upper and lower bounds for age, coverage, income, and duration. 2. Convert validated values to canonical decimal integers before arithmetic use. 3. Do not treat `bc` as a validation or sanitization layer. 4. Prefer passing fixed-format operands to `bc` only after strict allowlist validation. 5. Add regression tests containing shell metacharacters, command substitutions, array syntax, whitespace, signs, decimals, and extremely large values. 6. Reject invalid insurance types rather than silently applying a default rate. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/script.sh:6
Finding
Financial and Insurance Records Stored Without Enforced Restrictive Permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/script.sh`, lines 6-9 and 146-316 **Vulnerability Type**: Insecure storage of potentially sensitive user data **Risk Level**: Medium ### Vulnerable Code ```bash DATA_DIR="${HOME}/.local/share/insurance-advisor" mkdir -p "$DATA_DIR" _log() { echo "$(date '+%m-%d %H:%M') $1: $2" >> "$DATA_DIR/history.log"; } ``` Representative record-writing logic repeated across multiple commands: ```bash local input="$*" local ts=$(date '+%Y-%m-%d %H:%M') echo "$ts|$input" >> "$DATA_DIR/record.log" local total=$(wc -l < "$DATA_DIR/record.log") echo " [Insurance Advisor] record: $input" echo " Saved. Total record entries: $total" _log "record" "$input" ``` Equivalent plaintext writes occur for the `categorize`, `balance`, `trend`, `forecast`, `export-report`, `budget-check`, `summary`, `alert`, `history`, `compare`, and `tax-note` commands. ### Technical Analysis The script stores user-supplied financial or insurance-related information in predictable plaintext files under: ```text ~/.local/share/insurance-advisor ``` It does not set a restrictive `umask`, explicitly assign mode `0700` to the directory, or assign mode `0600` to the files. The resulting permissions therefore depend on the environment from which the script is invoked. The `_log` function also duplicates supplied information into `history.log`, increasing the number of locations containing potentially sensitive data. Export functions create further plaintext copies. There is a related functional defect: the command handlers use `local` at top-level script scope, although Bash permits `local` only within functions. With `set -e`, this may prevent the current handlers from completing. This defect does not remove the insecure-storage design: the implemented persistence and export paths remain plaintext and permission-dependent when reached or corrected. ### Attack Path 1. A user supplies financial, tax, insurance, health-related, or other p ...[truncated 994 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Enforce restrictive permissions before creating any records: ```bash umask 077 DATA_DIR="${HOME}/.local/share/insurance-advisor" mkdir -p -m 700 -- "$DATA_DIR" chmod 700 -- "$DATA_DIR" ``` Create files explicitly with user-only access: ```bash record_file="$DATA_DIR/record.log" touch -- "$record_file" chmod 600 -- "$record_file" printf '%s|%s\n' "$ts" "$input" >> "$record_file" ``` Further hardening should include: 1. Avoid duplicating full record contents in `history.log`; log only minimal event metadata. 2. Apply mode `0600` to all logs and generated exports. 3. Consider authenticated encryption for sensitive records at rest. 4. Document data retention and provide commands for secure deletion and export cleanup. 5. Warn users that exports contain sensitive plaintext. 6. Avoid placing sensitive values in terminal output where they may enter shell transcripts or process logs. 7. Move command handlers into functions or remove invalid top-level `local` declarations so security controls and functional tests can be applied consistently. 8. Add automated permission tests under permissive `umask` settings. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/script.sh:59
Finding
Unescaped Log Values Produce Unsafe JSON and CSV Exports<![CDATA[ ## Vulnerability Details **File Location**: `scripts/script.sh`, lines 59-92 **Vulnerability Type**: CSV formula injection and malformed structured-data generation **Risk Level**: Medium ### Vulnerable Code ```bash 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 "" >> "$out" echo "]" >> "$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 ;; ``` ### Technical Analysis Log fields are inserted directly into JSON strings without escaping quotation marks, backslashes, carriage returns, newlines, or other control characters. A crafted value can therefore invalidate the JSON structure or alter its logical contents. CSV output is assembled through comma concatenation without RFC-compliant quoting. Commas, quotation marks, and line breaks inside values can create additional cells or rows. Values beginning with spreadsheet formula prefixes such as `=`, `+`, `-`, or `@` may be interpreted as formulas when the exported file is opened by spreadsheet software. The current record handlers contain a separate top-level `local` defect that may prevent normal record creation. Nevertheless, the export routine processes all matching log files already present in the data directory, so malformed or attacker-influenced existing records remain a relevant input source. ### Attack Path 1. An attacker causes crafted content to be present in one of the log files processed by `_export`. This could occur through ...[truncated 1266 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Use dedicated serializers rather than constructing JSON or CSV through string interpolation. For JSON: 1. Use a trusted serializer such as `jq`. 2. Pass each value as data through `--arg`. 3. Never manually concatenate user-controlled JSON strings. Representative approach: ```bash jq -n \ --arg type "$name" \ --arg time "$ts" \ --arg value "$val" \ '{type: $type, time: $time, value: $value}' ``` For CSV: 1. Quote every field. 2. Escape each embedded double quote by doubling it. 3. Preserve embedded newlines according to the chosen CSV standard. 4. If files are intended for spreadsheet use, neutralize formula-leading values according to the target application's guidance. 5. Clearly distinguish machine-readable CSV from spreadsheet-safe CSV if both are required. Also add tests covering quotation marks, backslashes, commas, pipes, carriage returns, newlines, Unicode text, and values beginning with `=`, `+`, `-`, and `@`. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The description claims an insurance advisory tool focused on recommending insurance products, comparing plans, calculating premiums, and providing claims guidance. The code instead implements a generic command-line data recorder/reporting tool. Most commands simply append free-form input to category-specific .log files (record, categorize, balance, trend, forecast, budget-check, compare, tax-note, etc.), then provide export, search, stats, status, and history functions over those files. There is no logic for insurance product recommendation, policy comparison, premium computation, claims workflow assistance, or any insurance-domain rules. The primary purpose is materially different: local financial note/log management rather than insurance advice.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The implementation materially diverges from the declared insurance-advisor purpose and instead exposes a generic finance logging/export toolkit. This is dangerous because users and host platforms may grant trust, permissions, or handle sensitive insurance data under false assumptions, while the script persistently stores and exports broader financial inputs than expected.

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
The phrase “完全适配中文用户习惯” signals that the skill is tailored to a specific language/locale. The file does not offer a language choice or explain that the locale restriction is required for a region-specific purpose, which can violate the language/locale policy criteria.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The file labels the skill and presents its user-facing behavior in Chinese, and the commands later emit Chinese-only guidance. The policy requires flagging language or locale constraints when a skill forces a specific language without user opt-in or documented justification.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The claim guidance instructs users to gather and submit highly sensitive personal, banking, and medical documents, but it provides no privacy, minimization, or safe-handling warning. In an agent/skill context, this can normalize oversharing of protected information into chat logs, terminals, screenshots, or untrusted submission paths, increasing the risk of privacy breaches and identity or insurance fraud.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
Labeling the script as a generic finance tool directly contradicts the advertised insurance-advisor identity. Mislabeling is dangerous in a security review context because it indicates deceptive or careless packaging and makes it harder for users and reviewers to understand the real data-handling behavior of the skill.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The help output advertises many commands unrelated to the manifest while omitting the promised insurance recommendation, comparison, premium calculation, and claims guidance functions. This mismatch can mislead users into entering sensitive data for functions they did not consent to and is a strong indicator that the distributed skill does not match the reviewed description.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
Tax, budget, and forecasting features extend beyond the stated insurance-advisor use case and broaden the categories of sensitive financial data the tool may collect. Even without code execution, this creates a scope-creep/privacy risk because users may disclose more personal financial information than they intended based on the manifest.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script writes user inputs to persistent local log files and later supports export of those records without any explicit privacy notice, consent, retention policy, or redaction. In the context of an insurance advisor, users may provide highly sensitive health, policy, beneficiary, or financial details, making silent retention and export a meaningful confidentiality risk.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The markdown content from L03 onward is entirely in Chinese, including the substantive guidance and disclaimer. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation when no alternative language option or justification is provided.

Static analysis

No suspicious patterns detected.