Back to skill

Security audit

Income Tracker

Security checks for vulnerabilities and agentic risk

Overview

This is a purpose-aligned income tracker with local privacy and dependency hygiene cautions, but no evidence of exfiltration, hidden persistence, or destructive behavior.

Install only if you are comfortable storing income records locally in plaintext. Use a private DATA_PATH on a machine/account you control, avoid shared or synced folders unless you understand the exposure, and treat any future cloud-sync or backup feature as requiring separate review. Prefer regenerating the lockfile with an HTTPS npm registry before production use.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:100
Finding

Financial records are persisted in plaintext without restrictive filesystem permissions

Content
View full analysis

Vulnerability Details

File Location: index.js, lines 100-107
Vulnerability Type: Plaintext storage of sensitive financial data and insecure default file permissions
Risk Level: Medium

Vulnerable Code

javascript
function saveData(data, dataPath) {
  const dir = path.dirname(dataPath);
  if (!fs.existsSync(dir)) {
    fs.mkdirSync(dir, { recursive: true });
  }
  fs.writeFileSync(dataPath, JSON.stringify(data, null, 2));
}

Technical Analysis

The application serializes all income records directly into an unencrypted JSON file. These records may include income amounts, currencies, customer or platform names, project notes, tags, and timestamps.

Neither fs.mkdirSync nor fs.writeFileSync specifies a restrictive filesystem mode. Consequently, permissions are inherited from the process umask. Under a common umask of 0022, a newly created directory can be accessible with mode 0755 and a newly created file with mode 0644, allowing other local users to read the financial records.

The implementation also does not correct the permissions of an existing file. If the configured DATA_PATH references a file with overly broad permissions, subsequent writes preserve that exposure. The project documentation advises users to encrypt sensitive information, but the implementation does not provide encryption.

Attack Path

  1. A user runs the Skill with the default path or another path located on a multi-user system.
  2. The process creates the data directory and JSON file using permissions derived from a permissive umask.
  3. Income records, notes, and source information are written to the file in plaintext.
  4. Another local user or compromised process identifies the configured or default data path.
  5. If filesystem permissions permit access, that actor reads and exfiltrates the complete financial dataset.
  6. If an existing configured file is also writable by that actor, the actor can mo ...[truncated 614 chars]
Remediation
View remediation

Remediation Suggestions

  1. Create the storage directory with owner-only permissions:

    javascript
    fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
    
  2. Create and write the data file with mode 0600:

    javascript
    fs.writeFileSync(dataPath, JSON.stringify(data, null, 2), {
      encoding: 'utf8',
      mode: 0o600,
      flag: 'w'
    });
    
  3. Explicitly correct permissions on existing paths using fs.chmodSync(dir, 0o700) and fs.chmodSync(dataPath, 0o600) after validating ownership.

  4. Provide authenticated encryption for stored records, such as AES-GCM, with keys stored in an operating-system keychain or dedicated secrets manager rather than alongside the data file.

  5. Validate the configured path and reject symbolic links or unexpected file types where the deployment threat model includes local attackers. Atomic writes through a securely created temporary file should be used to prevent corruption.

  6. Document the confidentiality requirements and warn users before writing sensitive financial information to shared or network-mounted locations.

T08 · Insecure Dependencies

Note
Location
package-lock.json:25
Finding

Dependency archives are locked to an unencrypted third-party package mirror

Content
View full analysis

Vulnerability Details

File Location: package-lock.json, lines 25-88
Vulnerability Type: Insecure dependency transport and third-party registry configuration
Risk Level: Low

Vulnerable Code

The lockfile uses plaintext HTTP URLs for all resolved dependency archives. One complete affected package entry is:

json
"node_modules/ansi-styles": {
  "version": "4.3.0",
  "resolved": "http://mirrors.tencentyun.com/npm/ansi-styles/-/ansi-styles-4.3.0.tgz",
  "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
  "license": "MIT",
  "dependencies": {
    "color-convert": "^2.0.1"
  },
  "engines": {
    "node": ">=8"
  },
  "funding": {
    "url": "https://github.com/chalk/ansi-styles?sponsor=1"
  }
}

The same pattern occurs for asciichart, chalk, color-convert, color-name, dayjs, has-flag, and supports-color.

Technical Analysis

Dependency archives are resolved through http://mirrors.tencentyun.com rather than an HTTPS registry. Plaintext HTTP does not authenticate the package server and does not protect transport metadata or responses against network modification.

The SHA-512 integrity fields materially mitigate arbitrary package substitution because npm should reject an archive that does not match the locked digest. Therefore, a network attacker cannot normally replace a package with executable code while integrity verification is correctly enforced and the lockfile remains trusted.

Nevertheless, the insecure transport permits interception, redirection, response corruption, and denial of dependency installation. Malicious code substitution could become possible if integrity verification is disabled or bypassed, if tooling ignores the lockfile, or if the lockfile and dependency source are compromised together.

Attack Path

  1. A developer or build system runs npm install or npm ci.
  2. npm ret ...[truncated 1174 chars]
Remediation
View remediation

Remediation Suggestions

  1. Configure npm to use the official HTTPS registry or another organization-approved HTTPS registry:

    bash
    npm config set registry https://registry.npmjs.org/
    
  2. Regenerate the lockfile so every resolved field uses HTTPS:

    bash
    rm -rf node_modules package-lock.json
    npm install
    
  3. Review the regenerated dependency tree and commit the updated lockfile.

  4. Use npm ci in CI/CD environments to enforce the committed lockfile and integrity metadata.

  5. Prevent configuration from falling back to plaintext registries through repository-level .npmrc policy and CI validation.

  6. Add dependency scanning and lockfile checks that reject non-HTTPS resolved URLs before merging or releasing the package.

Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (14)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill advertises local storage, backup, export/import, and optional cloud sync for sensitive income data, but provides only minimal caution and no clear consent, retention, destination, or privacy details. Financial records can contain highly sensitive business and personal information, so unclear handling increases the risk of accidental disclosure, insecure sync, or unsafe imports/exports.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The shortcut trigger 收入 is very broad and likely to match many normal conversations about income, causing unintended invocation of the skill. For a finance-related skill that stores and analyzes user financial data, accidental activation can lead to unwanted data entry, exposure of private summaries, or confusing actions in the wrong context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Natural-language strings throughout the file, including the title and user-facing messages, are written only in Chinese, indicating the skill is designed to operate in a single language. There is no opt-in, fallback, or documentation stating that the locale restriction is intentional and limited to a region-specific use case.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This trigger is ambiguous and insufficiently specific, increasing the chance that normal discussion about earnings or records could activate the skill unintentionally. Because the skill handles personal financial records, mistaken activation can lead to privacy issues, incorrect logging, or confusing user experience.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The trigger phrase at this line is broad enough to appear in ordinary user conversation, which can cause unintended activation of the skill. In an income-tracking context, accidental invocation could expose or process financial data when the user did not explicitly intend to use this skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The description and most user-facing commands are presented in Chinese, but the file does not state that the skill is Chinese-only or provide an opt-in language choice. Under the policy, forcing a specific language without user choice can be a natural-language policy issue unless the locale restriction is clearly documented and justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill persists detailed income records, including amounts, dates, notes, and sources, to a local JSON file without any user-facing notice, consent flow, or retention controls. Because this data is financial and potentially sensitive, undisclosed persistence increases privacy risk, especially on shared machines or environments where the data directory may be backed up or accessed by other local users/processes.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The lockfile hard-codes an HTTP region-specific npm mirror (mirrors.tencentyun.com) for all package tarballs. This is risky because it bypasses the default trusted registry path, reduces supply-chain transparency for users, and uses an unencrypted transport that could permit tampering or interception despite integrity fields providing some downstream verification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The package description is written entirely in Chinese, which can constitute a language/locale policy concern when the skill does not indicate that Chinese is optional or that the package is intended only for a Chinese-speaking audience. There is no nearby justification or opt-in language showing that this locale choice is deliberate and scoped.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
87% confidence
Finding

Using a caret range for asciichart allows automatic installation of newer minor/patch releases, which can introduce supply-chain risk if an upstream package is compromised or a breaking change is published unexpectedly. In a finance-oriented skill, dependency trust matters because tampered packages could affect income data handling or terminal output integrity.

Content

Scanner excerpt · package.json (reported line 20)May include surrounding context.

json
"author": "clawd",
  "license": "MIT",
  "dependencies": {
    "asciichart": "^1.5.25",
    "chalk": "^4.1.2",
    "dayjs": "^1.11.10"
  },

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
87% confidence
Finding

Using a caret range for chalk permits unreviewed upstream updates within the allowed semver range, creating avoidable supply-chain exposure. Although chalk is a common library, compromise or malicious publishing could still impact execution of this Node-based skill.

Content

Scanner excerpt · package.json (reported line 21)May include surrounding context.

json
"license": "MIT",
  "dependencies": {
    "asciichart": "^1.5.25",
    "chalk": "^4.1.2",
    "dayjs": "^1.11.10"
  },
  "devDependencies": {},

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
88% confidence
Finding

Using a caret range for dayjs means installations may resolve to newer releases without explicit review, increasing supply-chain risk. Because this skill appears to process financial tracking data, even low-complexity dependency compromise could affect data correctness or leak information if malicious code were introduced upstream.

Content

Scanner excerpt · package.json (reported line 22)May include surrounding context.

json
"dependencies": {
    "asciichart": "^1.5.25",
    "chalk": "^4.1.2",
    "dayjs": "^1.11.10"
  },
  "devDependencies": {},
  "engines": {

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest predominantly specifies the skill in Chinese, including the description and most trigger phrases, without indicating that users can choose another language or that the locale restriction is intentional. This can create a language-policy issue if the skill is exposed to a broader user base without opt-in.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.