Back to skill

Security audit

Ticktick

Security checks for vulnerabilities and agentic risk

Overview

This TickTick skill is purpose-aligned, but its OAuth credential handling and unconfirmed task-changing commands deserve review before installation.

Install only if you are comfortable granting persistent TickTick read/write access to this skill. Prefer changing the setup flow before use so the OAuth client secret is entered interactively or via a protected channel instead of the command line, and be careful with edit, abandon, and batch-abandon because they change remote TickTick data without confirmation.

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
scripts/ticktick.ts:35
Finding

OAuth Client Secret Exposed Through Command-Line Arguments

Content
View full analysis
", "TickTick OAuth client ID") .option("--client-secret ", "TickTick OAuth client secret") ``` `scripts/ticktick.ts:57-58`: ```ts if (options.clientId && options.clientSecret) { await setupCredentials(options.clientId, options.clientSecret); } ``` `SKILL.md:17`: ```bash bun run scripts/ticktick.ts auth --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET ``` ### Technical Analysis The CLI accepts the TickTick OAuth client secret as a command-line argument, and the documented setup procedure explicitly instructs users to place the secret directly in the command. Command-line secrets can be exposed through: - Shell history files. - Process inspection utilities available to the same user or, depending on the operating system configuration, other local users. - Terminal session recording. - Command auditing and endpoint telemetry. - Automation logs that record invoked commands. - Error reports or support transcripts containing copied command lines. The subsequent storage code applies restrictive filesystem permissions, but those permissions do not protect the secret while it is being supplied through the process argument vector. ### Attack Path 1. A user follows the documented authentication command and includes the real client secret after `--client-secret`. 2. The shell records the complete command in its history, or local monitoring captures the process arguments. 3. An attacker with access to the affected history, logs, terminal recording, or process metadata retrieves the OAuth client secret. 4. The attacker uses the secret to impersonate the registered OAuth client in protocol interactions. ...[truncated 706 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/auth.ts:299
Finding

Manual OAuth Error Handling Can Disclose the Authorization Callback URL

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • 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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (21)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The stated purpose is simple task management, but the skill also performs OAuth login, runs an authentication flow, and stores long-lived credentials and tokens on disk. This behavior expansion materially changes the trust model: users may invoke a benign-seeming productivity skill without realizing it can obtain persistent account access and manage secrets locally.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: js-yaml==4.1.1 — 4 advisory(ies): CVE-2026-84375 (js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources); CVE-2026-59869 (js-yaml: YAML merge-key chains can force quadratic CPU consumption); GHSA-5p4m-2wfm-xmqj (JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) — CVE-2026) +1 more

High
Category
Supply Chain
Confidence
96% confidence
Finding

The lockfile pins js-yaml to 4.1.1, and the reported advisories indicate parser-level denial-of-service issues involving merge keys and object-map resolution that can trigger excessive CPU consumption on crafted YAML input. In a task-management CLI/agent skill, YAML is likely used for configuration or data import, so if the tool parses untrusted or user-supplied YAML, an attacker could cause hangs or resource exhaustion.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: js-yaml==4.1.1 — 4 advisory(ies): CVE-2026-84375 (js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources); CVE-2026-59869 (js-yaml: YAML merge-key chains can force quadratic CPU consumption); GHSA-5p4m-2wfm-xmqj (JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) — CVE-2026) +1 more

High
Category
Supply Chain
Confidence
97% confidence
Finding

The package explicitly depends on js-yaml 4.1.1, which is identified as having multiple known denial-of-service vulnerabilities involving excessive CPU consumption during YAML parsing. In a CLI skill that may ingest user-controlled configuration or task import data, malformed YAML could cause the process to hang or consume significant resources, making the skill less reliable and potentially abusable.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/auth.ts (reported line 63)May include surrounding context.

ts
if (!config.accessToken) {
    throw new Error(
      "No access token found. Run 'ticktick auth' to authenticate."
    );
  }

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill documents shell execution, network access, environment usage, and credential handling, but declares no explicit tool scope or permission boundaries. In an agent environment, missing scope declarations can cause overbroad runtime privileges and make it harder for the platform or user to constrain what the skill is allowed to do.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill exposes destructive actions like abandon, batch-abandon, complete, and edit without any confirmation, preview, or warning guidance. In an agentic context, ambiguous prompts, mistaken task IDs, or prompt injection through surrounding conversation could lead to unintended bulk changes to a user's task state.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The handler supports state-changing operations such as creating tasks, completing tasks, and abandoning tasks, then immediately executes them. While the file has a top-level doc comment for developers, there is no runtime confirmation prompt or explicit user-facing warning before these modifications occur.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code builds a shell command string from untrusted command-line arguments using string concatenation and passes it to Bun.spawnSync(cmd, ...). If Bun executes this string via a shell, an attacker can inject additional shell metacharacters or commands through task titles or options, leading to arbitrary command execution in the skill's environment.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/api.ts (reported line 3)May include surrounding context.

ts
import { getValidToken } from "./auth";

const API_BASE = "https://api.ticktick.com/open/v1";

export interface Project {
  id: string;

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/auth.ts (reported line 13)May include surrounding context.

ts
import { getValidToken } from "./auth";

const API_BASE = "https://api.ticktick.com/open/v1";

export interface Project {
  id: string;

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The skill includes remote state-changing operations to complete and delete tasks via POST/DELETE requests, which can affect user data irreversibly. While the methods are named clearly for developers, this file provides no user-facing confirmation, warning comment, or disclosure around these actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code changes the task status to an abandoned state, which is a destructive or potentially irreversible operation. Although the command prints a success message afterward, there is no prior confirmation prompt, warning comment/docstring, or other user disclosure in this file before performing the update.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

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

json
"ticktick": "./scripts/ticktick.ts"
  },
  "dependencies": {
    "commander": "^12.0.0",
    "js-yaml": "^4.1.1",
    "open": "^10.0.0",
    "ts-node": "^10.9.2"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

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

json
},
  "dependencies": {
    "commander": "^12.0.0",
    "js-yaml": "^4.1.1",
    "open": "^10.0.0",
    "ts-node": "^10.9.2"
  },

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

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

json
"dependencies": {
    "commander": "^12.0.0",
    "js-yaml": "^4.1.1",
    "open": "^10.0.0",
    "ts-node": "^10.9.2"
  },
  "devDependencies": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

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

json
"commander": "^12.0.0",
    "js-yaml": "^4.1.1",
    "open": "^10.0.0",
    "ts-node": "^10.9.2"
  },
  "devDependencies": {
    "@types/bun": "^1.0.0"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

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

json
"ts-node": "^10.9.2"
  },
  "devDependencies": {
    "@types/bun": "^1.0.0"
  }
}

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The command calls api.completeTask(projectId, task.id), which changes remote task state. While 'manage' broadly permits mutation, the file's user-facing messaging centers on obtaining IDs from /tasks --json, which suggests a listing-oriented workflow and does not make the destructive state change explicit in this command's own behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code explicitly formats dates with toLocaleString("en-US", ...), which imposes a specific language/locale regardless of user preferences. This is a natural-language/locale policy issue because the skill does not offer a locale choice or document a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The call to toLocaleDateString uses a hard-coded "en-US" locale, which forces output formatting to a specific language/locale regardless of user preferences. This matches the policy concern for locale restrictions when no opt-in, fallback, or justification is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code explicitly formats dates with toLocaleDateString('en-US', ...), which forces a specific locale regardless of the user's preferences or system settings. This is a natural-language/locale policy issue because it imposes U.S. English formatting without offering a choice or documenting a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/auth.ts:103