Back to skill

Security audit

Income Tracker

Security checks for vulnerabilities and agentic risk

Overview

This income-tracking skill behaves like a local finance log, but users should understand it stores income records in plaintext and has some dependency hardening issues.

Install only if you are comfortable keeping income records in a local plaintext JSON file. Use a private data path, restrict filesystem permissions, avoid shared machines for this data, and consider regenerating dependencies from a trusted HTTPS npm registry before running it.

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)

T08 · Insecure Dependencies

Warning
Location
package-lock.json:18
Finding

Dependencies Retrieved over Unencrypted HTTP

Content
View full analysis

Vulnerability Details

File Location: package-lock.json:18-21
Vulnerability Type: Insecure dependency source and transport
Risk Level: Medium

Vulnerable Code

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==",

The same plaintext mirror is used for all locked dependencies at package-lock.json:20,36,42,58,70,76,82.

Technical Analysis

Dependency archives are resolved through http://mirrors.tencentyun.com rather than an authenticated HTTPS registry. Plaintext HTTP does not provide transport confidentiality or server authentication, allowing an on-path attacker to observe, redirect, block, or replace dependency responses.

The lockfile contains SHA-512 integrity values, so a normal npm installation should reject modified archives whose contents do not match the recorded hashes. This substantially limits direct package substitution when the lockfile remains trusted. It does not prevent denial of service, dependency-request monitoring, mirror impersonation attempts, or compromise where an attacker can also modify the lockfile or its integrity metadata.

The project also declares asciichart and chalk, although the reviewed implementation does not import either dependency. Unnecessary dependencies increase the supply-chain attack surface.

Attack Path

  1. A developer or deployment system runs npm install using the committed lockfile.
  2. npm requests dependency archives through plaintext HTTP.
  3. An attacker positioned on the network intercepts or redirects these requests.
  4. The attacker can block or corrupt responses, causing installation failure.
  5. Arbitrary substituted content should fail npm integrity verification while the lockfile is trusted.
  6. If the attacker can also ...[truncated 710 chars]
Remediation
View remediation

Remediation Suggestions

  1. Configure npm to use the official HTTPS registry or another explicitly trusted HTTPS registry:
    bash
    npm config set registry https://registry.npmjs.org/
    
  2. Delete and regenerate package-lock.json from the trusted registry, then verify that every resolved URL uses HTTPS.
  3. Pin and review dependency versions through the lockfile in CI.
  4. Run dependency integrity and vulnerability checks during builds, such as npm ci and npm audit.
  5. Remove the unused asciichart and chalk dependencies to reduce supply-chain exposure.
  6. Protect the lockfile through branch review, signed commits where practical, and CI checks that reject plaintext dependency URLs.

T09 · Insecure Skill Coding Practices

Note
Location
index.js:96
Finding

Sensitive Financial Records Written without Explicit Access Restrictions or Encryption

Content
View full analysis

Vulnerability Details

File Location: index.js:96-102
Vulnerability Type: Plaintext sensitive-data storage with process-default permissions
Risk Level: Low

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 income amounts, currencies, sources, dates, notes, and tags directly into a plaintext JSON file. Neither the directory nor file is created with an explicit owner-only mode. Effective permissions therefore depend on the runtime account's umask, existing directory permissions, and permissions of an existing destination file.

On systems with permissive defaults or shared accounts, another local user or process may be able to read the stored financial records. The Skill documentation advises encrypting sensitive data, but encryption is not implemented. Existing files are also overwritten without checking or tightening their permissions.

Attack Path

  1. A user invokes the add or record action with financial information.
  2. saveData creates the parent directory using default permissions and writes the JSON file using process-default or existing file permissions.
  3. The host has a permissive umask, a shared parent directory, or an existing broadly readable destination file.
  4. Another local account or process enumerates and reads the data file.
  5. The reader obtains recorded income amounts, sources, dates, notes, tags, and associated financial patterns.

This path requires local filesystem access and permissive effective permissions; no remote access or privilege escalation is demonstrated.

Impact Assessment

Successful exploitation exposes the financial records stored in the configured data file. The scope is limited to data accessib ...[truncated 258 chars]

Remediation
View remediation

Remediation Suggestions

  1. Create the storage directory with owner-only permissions:
    javascript
    fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
    
  2. Write new files with mode 0600 and explicitly tighten existing file permissions:
    javascript
    fs.writeFileSync(dataPath, JSON.stringify(data, null, 2), { mode: 0o600 });
    fs.chmodSync(dataPath, 0o600);
    
  3. Verify that the destination is a regular file and reject symbolic links where the deployment threat model includes untrusted local users.
  4. Use atomic writes through a securely created temporary file in the same protected directory, followed by a rename.
  5. Offer authenticated encryption for financial data, with keys stored outside the data file and obtained from an operating-system key store or secret manager.
  6. Document the confidentiality model and warn users when an existing data file or parent directory has overly broad permissions.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (15)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill references an environment-dependent capability via configuration and implied runtime handling, but it does not declare any explicit tool scope or permissions boundaries. This can lead to over-broad execution context, unclear trust assumptions, and accidental access to capabilities the user did not expect.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The trigger set includes broad, natural-language phrases such as common income-related requests that a user might say conversationally, increasing the chance of unintended invocation. In a finance-related skill, accidental activation can expose or modify sensitive income records without the user explicitly intending to use this skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill advertises cloud sync and real-time exchange-rate usage but does not clearly disclose what data is transmitted, to which services, or under what consent model. For financial records, silent or poorly documented network transmission creates privacy and data-handling risk, especially if notes, sources, or amounts are sent externally.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The shortcut command 收入 is extremely vague and overlaps with ordinary speech, making accidental invocation likely. Because the skill deals with personal financial data, an unintended launch could reveal sensitive summaries or lead users into interacting with the wrong skill context.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Shortcuts like 月报 and 趋势 are ambiguous, broadly applicable terms that are not uniquely tied to this skill. This raises the risk of unintended invocation or confusion with other reporting/charting skills, which is more concerning here because the data involved is financial and potentially sensitive.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The skill stores sensitive financial data locally and permits manual editing, but the warning is minimal and does not set strong expectations around access control, file permissions, tamper risks, or encryption. This can leave users with exposed income histories or corrupted records if the file is accessed by other local users or modified unsafely.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Natural-language strings throughout the file, including the title, comments, status messages, report labels, and suggestions, are in Chinese, indicating the skill operates in a fixed language. There is no visible opt-in, locale selection, or documentation that this is a region-specific tool, which conflicts with the policy against forcing a language without user choice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill persists potentially sensitive financial data, including income amounts, dates, notes, and sources, to a local JSON file without any user-facing disclosure, consent flow, or retention guidance. In the context of an income tracker, this creates a real privacy risk because users may assume the data is ephemeral while it is actually stored on disk in a predictable location or one controlled by the DATA_PATH environment variable.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The natural-language metadata, including the description, config description, features, and most trigger phrases, are presented only in Chinese, which imposes a language expectation without offering user choice. There is no indication that the skill is region-specific or that alternate language support is available.

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 location is broad enough to match ordinary user requests about viewing income, which can cause the skill to activate unintentionally. In an agent ecosystem, accidental invocation can lead to confusing behavior, privacy issues around financial data entry/display, or trigger hijacking where this skill intercepts requests intended for another tool.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
70% confidence
Finding

The documented default settings include "Asia/Shanghai" and the skill description is primarily Chinese, which may imply a fixed locale expectation. The file does not explicitly offer users a language or locale choice or explain that the locale is configurable based on user preference.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The description is written entirely in Chinese, which can constitute a language/locale policy issue when the skill does not indicate that Chinese is optional or that the skill is intended only for a Chinese-speaking audience. In a manifest file, this natural-language constraint can affect discoverability and user expectations across broader audiences.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
88% confidence
Finding

Using caret-ranged dependencies allows future compatible releases to be installed automatically, which can introduce vulnerable or compromised upstream versions via the supply chain. In a package.json file this is a real, though low-severity, supply-chain hardening issue because runtime behavior depends on external packages that are not strictly fixed.

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
88% confidence
Finding

The caret version for chalk permits automatic adoption of later patch/minor releases, increasing exposure to accidental breakage or malicious supply-chain updates. While common in JavaScript ecosystems, it weakens build reproducibility and dependency integrity.

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

The dayjs dependency is not pinned to an exact version, so installations may resolve to different upstream releases over time. That creates a low-grade supply-chain risk if a later allowed release contains a vulnerability or malicious code.

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": {

Static analysis

No suspicious patterns detected.