Back to skill

Security audit

SubsTracker

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to do what it claims for SubsTracker, but it handles credentials, sessions, and destructive account data with weak scoping and safety controls that users should review before installing.

Install only if you intend agents to manage your SubsTracker instance directly. Use an HTTPS `SUBSTRACKER_URL`, avoid running it from untrusted working directories, protect `~/.substracker-skills` with private permissions, avoid putting passwords or API tokens in command-line flags, and manually confirm any delete, password, webhook, or notification-token changes before allowing the agent to run them.

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

T08 · Insecure Dependencies

Warning
Location
SKILL.md:48
Finding

Unpinned Runtime Package Is Automatically Downloaded and Executed

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/client.ts:35
Finding

Credentials and Session Data Can Be Transmitted over Plaintext HTTP

Content
View full analysis
{ const cfg = getConfig(); const res = await fetch(`${cfg.SUBSTRACKER_URL}/api/login`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ username: cfg.SUBSTRACKER_USER, password: cfg.SUBSTRACKER_PASS }), redirect: "manual", }); ``` ```ts const res = await fetch(`${cfg.SUBSTRACKER_URL}${endpoint}`, { method, headers, body: body ? JSON.stringify(body) : undefined, redirect: "manual", }); ``` ### Technical Analysis `SUBSTRACKER_URL` is accepted without parsing or validating its protocol. If it uses `http:`, the client sends the administrative username and password, session cookie, subscription informati ...[truncated 1443 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/client.ts:64
Finding

Persistent Session Cookie Is Written without Explicit Restrictive Permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.ts:8
Finding

Administrative Passwords and API Tokens Are Accepted through Command-Line Arguments

Content
View full analysis
{ const flags: Record = {}; for (let i = 0; i < args.length; i++) { const arg = args[i]!; if (arg.startsWith("--")) { const key = arg.slice(2); const next = args[i + 1]; if (next && !next.startsWith("--")) { flags[key] = next; i++; } else { flags[key] = true; } } } return flags; } ``` The values are then sent to the configured API: ```ts export async function update(flags: Record) { const cfg: AppConfig = {}; if (flags["username"]) cfg.ADMIN_USERNAME = flags["username"] as string; if (flags["password"]) cfg.ADMIN_PASSWORD = flags["password"] as string; if (flags["tg-bot-token"]) cfg.TG_BOT_TOKEN = flags["tg-bot-token"] as string; if (flags["tg-chat-id"]) cfg.TG_CHAT_ID = flags["tg-chat-id"] as string; if (flags["timezone"]) cfg.TIMEZONE = flags["timezone"] as string; if (flags["show-lunar"] !== undefined) cfg.SHOW_LUNAR = flags["show-lunar"] !== "false"; if (flags["theme"]) cfg.THEME_MODE = flags["theme"] as string; if (flags["notifiers"]) cfg.ENABLED_NOTIFIERS = (flags["notifiers" ...[truncated 2965 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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
Findings (16)

Vague Triggers

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The invocation description is extremely broad and triggers on generic phrases about subscriptions, bills, renewals, or notifications, even when the user does not mention SubsTracker. That can cause over-eager activation of a credentialed skill, leading the agent to access a user's local configuration, authenticated session, or remote instance in contexts where the user only wanted general advice or a different service.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/client.ts (reported line 36)May include surrounding context.

ts
}

export function loadConfig(): SubsTrackerEnv {
  const cwdEnvPath = path.join(process.cwd(), ".substracker-skills", ".env");
  const homeEnvPath = path.join(os.homedir(), ".substracker-skills", ".env");

  const cwdEnv = loadEnvFile(cwdEnvPath);

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/client.ts (reported line 37)May include surrounding context.

ts
}

export function loadConfig(): SubsTrackerEnv {
  const cwdEnvPath = path.join(process.cwd(), ".substracker-skills", ".env");
  const homeEnvPath = path.join(os.homedir(), ".substracker-skills", ".env");

  const cwdEnv = loadEnvFile(cwdEnvPath);

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/client.ts (reported line 55)May include surrounding context.

ts
if (missing.length) {
    throw new Error(
      `Missing: ${missing.join(", ")}.\n` +
      "Set via environment variables or in .substracker-skills/.env file."
    );
  }

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/main.ts (reported line 59)May include surrounding context.

ts
if (missing.length) {
    throw new Error(
      `Missing: ${missing.join(", ")}.\n` +
      "Set via environment variables or in .substracker-skills/.env file."
    );
  }

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill documents code execution that reads environment variables and performs authenticated network requests, but it does not declare an explicit tool scope such as allowed tools or permissions. This creates unclear trust boundaries: an agent may invoke a networked, credential-using skill without transparent policy constraints, increasing the chance of unintended secret access or outbound requests.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation instructs the use of .env credentials and numerous secret-bearing config flags such as passwords, bot tokens, webhook URLs, and API keys, but it lacks explicit warnings about sensitive-data handling. In practice this increases the risk that users or agents will expose secrets in command lines, logs, screenshots, shell history, or conversational transcripts.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding

Using npx -y bun without a pinned version allows execution of whatever package/version is resolved at runtime. If the registry content changes or a malicious package/version is served, the agent could run untrusted code with the same environment and network access as the skill, potentially exposing credentials or altering behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The client persists the raw Set-Cookie header to a file in the user's home directory without setting restrictive file permissions or limiting the stored value to the session cookie only. If another local user, process, backup system, or malware can read that file, the session token may be replayed to impersonate the user against the SubsTracker instance.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The login function sends stored credentials to a remote /api/login endpoint, which is a network operation involving sensitive data. While the code is clear to a developer, there is no confirmation prompt, user-facing notice, or warning comment/docstring near this behavior in the file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code collects and transmits multiple sensitive values such as admin credentials, bot tokens, API keys, and webhook endpoints via a POST request. There is no confirmation prompt, user-facing log/print, or explanatory comment/docstring in this file warning that secrets will be sent to the server.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This CLI routes subscriptions delete and payments delete directly to deletion handlers, but the visible help text and command handling here do not provide any confirmation prompt or explicit warning that the operation removes data. Because these are destructive operations, users should receive a clear disclosure before invocation or execution unless that warning is documented elsewhere.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

At L23, the function submits the assembled input object to /api/test-notification via a POST request. The input may include user-provided overrides such as bot tokens or webhook-related values derived at L12-L19, but this file provides no confirmation, logging, or user-facing warning that such data will be transmitted.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The del function performs a DELETE request against a payment resource, which is a destructive operation. In this file there is no confirmation prompt, logging, print statement, or explanatory comment/docstring warning that a payment record will be deleted.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code file exposes a destructive operation via del(id) that issues a DELETE request, but there is no confirmation prompt, logging, print statement, or comment explaining the impact to the user. Under the code-file criteria, destructive or irreversible operations should have some visible disclosure unless the warning is provided elsewhere, which is not evident in this file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The file embeds a China-specific default currency (CNY) and elsewhere uses Chinese-language example/category strings and note defaults, which collectively indicate a fixed language/locale assumption. Because there is no nearby opt-in, locale selection, or documented regional scope, this can violate the policy against forcing a specific language or locale by default.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access, suspicious.exposed_secret_literal, suspicious.potential_exfiltration

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/client.ts:42

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/client.ts:96

Sensitive-looking file read is paired with a network send.

Warn
Code
suspicious.potential_exfiltration
Location
scripts/client.ts:71