Back to skill

Security audit

Daily Income Logger

Security checks for vulnerabilities and agentic risk

Overview

This skill is a straightforward local income logger, but users should understand it stores financial records in plaintext and its sample shell commands need hardening.

Install only if you are comfortable keeping income records in a local plaintext JSON file. On shared machines, harden the commands before use by setting owner-only directory/file permissions, avoiding a fixed tmp.json path, and using a lock or atomic temp file for updates.

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
SKILL.md:63
Finding

Predictable Temporary File Enables Symlink Attacks and Data Corruption

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 63-66
Vulnerability Type: Predictable and unsafe temporary file usage
Risk Level: Medium

bash
jq --arg date "$TODAY" --arg ts "$TIMESTAMP" --arg platform "$PLATFORM" \
   --arg amount "$AMOUNT" --arg note "$NOTE" \
   '.records += [{"date":$date,"timestamp":$ts,"platform":$platform,"amount":($amount | tonumber),"note":$note}]' \
   "$INCOME_FILE" > tmp.json && mv tmp.json "$INCOME_FILE"

Technical Analysis

The record operation writes its result to a fixed relative path named tmp.json. The location is derived from the process's current working directory rather than a private data directory, and the file is created through ordinary shell redirection without exclusive-creation or symbolic-link protections.

If another local user or process can modify the working directory, it can pre-create tmp.json as a symbolic link. Shell redirection follows that link and truncates or overwrites its target using the privileges of the user running the Skill. The subsequent mv can also replace the income database with the attacker-created symbolic link.

Concurrent invocations use the same temporary path and read the same original database state. They can overwrite one another's temporary output or cause one invocation to move a file expected by another, resulting in lost records or operation failure.

Attack Path

  1. The victim invokes the documented income-recording command from a shared or attacker-writable working directory.
  2. Before invocation, a local attacker creates tmp.json as a symbolic link to a file writable by the victim.
  3. The shell follows the link while processing the output redirection and truncates or replaces the target's contents with JSON output.
  4. The mv operation moves the symbolic link to ~/.daily-income-logger/data/income.json, potentially leaving the income database linked to the attacker-selected target. 5 ...[truncated 785 chars]
Remediation
View remediation

Remediation Suggestions

  • Create the temporary file inside the private data directory with mktemp, rather than using a fixed relative name.
  • Register a trap to remove the temporary file on normal exit, interruption, or failure.
  • Rename the temporary file only after jq completes successfully.
  • Use a lock such as flock around the complete read-modify-write transaction to prevent lost updates.
  • Verify that the destination is a regular file and not a symbolic link before reading or replacing it.
  • Keep the temporary file on the same filesystem as the destination so the final rename is atomic.

Example hardened pattern:

bash
LOCK_FILE="$DATA_DIR/data/income.lock"

(
  flock -x 9
  TMP_FILE=$(mktemp "$DATA_DIR/data/income.json.XXXXXX") || exit 1
  trap 'rm -f "$TMP_FILE"' EXIT

  jq --arg date "$TODAY" --arg ts "$TIMESTAMP" \
     --arg platform "$PLATFORM" --arg amount "$AMOUNT" --arg note "$NOTE" \
     '.records += [{
       "date": $date,
       "timestamp": $ts,
       "platform": $platform,
       "amount": ($amount | tonumber),
       "note": $note
     }]' "$INCOME_FILE" > "$TMP_FILE" || exit 1

  chmod 600 "$TMP_FILE"
  mv -- "$TMP_FILE" "$INCOME_FILE" || exit 1
  trap - EXIT
) 9>"$LOCK_FILE"

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:46
Finding

Financial Records Are Stored Without Enforced Access Permissions

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 46-59
Vulnerability Type: Insecure permissions for plaintext sensitive data
Risk Level: Medium

bash
DATA_DIR="$HOME/.daily-income-logger"
mkdir -p "$DATA_DIR/data"

PLATFORM=$1
AMOUNT=$2
NOTE=${3:-""}
TODAY=$(date +%Y-%m-%d)
TIMESTAMP=$(date -Iseconds)

INCOME_FILE="$DATA_DIR/data/income.json"

# 初始化或读取现有数据
if [ ! -f "$INCOME_FILE" ]; then
  echo '{"records":[]}' > "$INCOME_FILE"
fi

Technical Analysis

The Skill stores income amounts, platforms, timestamps, and user notes in a plaintext JSON file. Neither directory creation nor file creation explicitly enforces owner-only permissions.

mkdir -p and shell redirection apply permissions according to the invoking process's current umask. Under a permissive configuration, the directories may be accessible to other local users and income.json may be created as group-readable or world-readable. The code also does not correct the permissions of an existing directory or database file.

Because the database is directly writable when its permissions permit it, exposure is not limited to confidentiality. Another local account may also alter amounts, insert fabricated records, remove records, or replace the file with another filesystem object.

Attack Path

  1. The Skill is run in an environment with a permissive umask or with pre-existing permissive data-directory permissions.
  2. ~/.daily-income-logger/data and income.json are created without explicit owner-only modes.
  3. Another local user enumerates and reads the database to obtain platform names, income amounts, timestamps, and notes.
  4. If write permissions are also available, that user modifies or deletes the JSON data, causing inaccurate reports or loss of records.

Exploitation requires local filesystem access through another account or process and permissions allowed by the effective umask or pre-existing modes. ...[truncated 386 chars]

Remediation
View remediation

Remediation Suggestions

  • Set umask 077 before creating any directory or file containing financial information.
  • Create the application and data directories with mode 700.
  • Create the database with mode 600, and correct the mode of an existing database before use.
  • Reject a database path that is a symbolic link or is not a regular file.
  • Document that the records are stored in plaintext and rely on operating-system account and filesystem security.
  • If the threat model includes administrators, device theft, or offline disk access, use encrypted storage or require full-disk encryption.

Example hardening:

bash
umask 077

DATA_DIR="$HOME/.daily-income-logger"
mkdir -p -m 700 "$DATA_DIR/data"
chmod 700 "$DATA_DIR" "$DATA_DIR/data"

INCOME_FILE="$DATA_DIR/data/income.json"

if [ -L "$INCOME_FILE" ]; then
  echo "Refusing to use a symbolic link as the income database" >&2
  exit 1
fi

if [ ! -e "$INCOME_FILE" ]; then
  printf '%s\n' '{"records":[]}' > "$INCOME_FILE"
elif [ ! -f "$INCOME_FILE" ]; then
  echo "Income database is not a regular file" >&2
  exit 1
fi

chmod 600 "$INCOME_FILE"
Vulnerability Patterns
  • 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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (2)

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The natural-language content of the skill is entirely in Chinese and the usage examples assume Chinese interaction, but the document does not state that the skill is region-specific or provide an opt-in language choice. Under the policy, forcing a specific language or locale without user choice is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The natural-language description is written only in Chinese and provides no indication that the skill is intended for a Chinese-speaking audience or that users can choose another language. Under the policy rule for language/locale constraints, this can be interpreted as forcing a specific language without user opt-in or justification.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.