Back to skill

Security audit

Multi-Channel Income Tracker

Security checks for vulnerabilities and agentic risk

Overview

This is a simple local income and expense tracker that stores records on disk for reporting, with privacy caveats but no evidence of hidden or malicious behavior.

Before installing, be aware that income and expense entries, including descriptions, are saved locally in plaintext under your home directory. Avoid putting secrets or highly sensitive personal details in descriptions, and use this on a machine where your home directory permissions are private.

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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
tracker.js:6
Finding

Financial Records Stored Without Explicitly Restrictive Permissions

Content
View full analysis

Vulnerability Details

File Location: tracker.js, lines 6-47
Vulnerability Type: Plaintext sensitive-data storage with permissions inherited from the process environment
Risk Level: Medium

js
const DATA_DIR = path.join(process.env.HOME, '.openclaw/workspace/data/income');
const INCOME_FILE = path.join(DATA_DIR, 'income.jsonl');
const EXPENSE_FILE = path.join(DATA_DIR, 'expenses.jsonl');

// Ensure data directory exists
if (!fs.existsSync(DATA_DIR)) {
  fs.mkdirSync(DATA_DIR, { recursive: true });
}

function addIncome(source, amount, description) {
  const entry = {
    timestamp: new Date().toISOString(),
    source,
    amount: parseFloat(amount),
    description,
    type: 'income'
  };
  
  fs.appendFileSync(INCOME_FILE, JSON.stringify(entry) + '\n');
  console.log(`✅ Added income: $${amount} from ${source}`);
}

function addExpense(category, amount, description) {
  const entry = {
    timestamp: new Date().toISOString(),
    category,
    amount: parseFloat(amount),
    description,
    type: 'expense'
  };
  
  fs.appendFileSync(EXPENSE_FILE, JSON.stringify(entry) + '\n');
  console.log(`✅ Added expense: $${amount} for ${category}`);
}

Technical Analysis

The application stores transaction timestamps, amounts, income sources, expense categories, and user-supplied descriptions in plaintext JSONL files. Neither fs.mkdirSync nor fs.appendFileSync specifies an explicit restrictive mode. Consequently, newly created directory and file permissions depend on the process umask and surrounding filesystem configuration.

On a system with a permissive umask or improperly configured parent directories, other local users may be able to traverse the data directory and read the financial records. Free-form descriptions may increase the sensitivity of the exposed data if users enter customer names, project details, invoice references, or other confidential inform ...[truncated 1740 chars]

Remediation
View remediation

Remediation Suggestions

  • Create the data directory with mode 0700, for example:
    js
    fs.mkdirSync(DATA_DIR, { recursive: true, mode: 0o700 });
    fs.chmodSync(DATA_DIR, 0o700);
    
  • Create transaction files with mode 0600. Prefer opening them with flags that safely create the file and explicitly constrain its permissions before writing.
  • Use fs.lstatSync to reject symbolic links and verify that each storage object is a regular file owned by the expected user before appending.
  • Consider using O_NOFOLLOW where supported to reduce symbolic-link race exposure.
  • Fail closed when ownership or permissions are broader than expected rather than silently continuing.
  • Document that records are retained in plaintext and advise users not to place secrets, credentials, or unnecessary personal data in transaction descriptions.
  • If the threat model includes untrusted local users or shared backups, protect records with authenticated encryption and store encryption keys separately using an operating-system credential facility.
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)

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code appends income entries to a persistent file under the user's home directory, which affects user data by creating and modifying local records. Although there is a success message after the write, there is no prior disclosure in comments, docstrings, or surrounding skill description here that the tool stores financial data on disk at a specific path.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The function appends expense data to expenses.jsonl in the user's home-directory workspace, which is a file write affecting user data. The success log confirms completion but does not adequately warn beforehand that personal financial information will be stored persistently on disk.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.