Back to skill

Security audit

TickTick CLI

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent TickTick command-line skill, but it handles TickTick OAuth secrets and can change tasks, so users should treat its local config and mutation commands carefully.

Install only if you are comfortable granting TickTick task read/write access. Avoid pasting real client secrets into shared terminals or automation logs, protect ~/.clawdbot/credentials/ticktick-cli/config.json, and verify task IDs carefully before using abandon or batch-abandon.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ticktick.ts:28
Finding

OAuth Client Secret Exposed Through Command-Line Arguments

Content
View full analysis
", "TickTick OAuth client ID") .option("--client-secret ", "TickTick OAuth client secret") .option("--manual", "Manual auth flow for headless servers (paste redirect URL)") .option("--logout", "Clear authentication tokens") .option("--status", "Check authentication status") .action(async (options) => { // ... if (options.clientId && options.clientSecret) { await setupCredentials(options.clientId, options.clientSecret); } ``` The documented invocation directly places the secret on the command line: ```bash # Set credentials and start OAuth flow bun run scripts/ticktick.ts auth --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET ``` ### Technical Analysis The CLI requires the OAuth client secret to be supplied as an ordinary command-line argument. Depending on the operating system and execution environment, command-line arguments may be exposed through: - Shell history files. - Process inspection interfaces and tools. - Process accounting or endpoint monitoring. - CI/CD command logs. - Terminal recording and diagnostic collection. - Agent execution transcripts. Although the client secret does not independently grant access to the user's TickTick account, it is sensitive OAuth application material. Its disclosure weakens the OAuth client authentication boundary and can contribute to abuse when combined with intercepted authorization codes, refresh tokens, or other credentials. Accepting the secret in this manner is unnecessary because it can instead be collected through non-echoing interactive input or a protected file descriptor. ### Attack Path 1. A user follows the documented setup command and supplies ...[truncated 990 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/auth.ts:46
Finding

OAuth Client Credentials and Tokens Stored in Plaintext

Content
View full analysis
{ await ensureConfigDir(); await writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 0o600 }); await chmod(CONFIG_DIR, 0o700).catch(() => {}); await chmod(CONFIG_FILE, 0o600).catch(() => {}); } export async function setupCredentials( clientId: string, clientSecret: string ): Promise { const config = (await loadConfig()) || ({} as TickTickConfig); config.clientId = clientId; config.clientSecret = clientSecret; config.redirectUri = DEFAULT_REDIRECT_URI; await saveConfig(config); console.log("Credentials saved successfully."); } ``` After authentication, the same configuration object is populated with access and refresh tokens and serialized by `saveConfig`: ```ts config.accessToken = tokenData.access_token; config.refreshToken = tokenData.refresh_token; config.tokenExpiry = Date.now() + tokenData.expires_in * 1000; await saveConfig(config); ``` ### Technical Analysis The configuration file contains the OAuth client secret, access token, and refresh token as unencrypted JSON. The code appropriately attempts to restrict the directory to mode `0700` and the file to mode `0600`; however, these permissions only limit access between ordinary local accounts. They do not protect the secrets from: - Malware or compromised processes running under the same user account. - Accidental inclusion in backups, snapshots, or suppor ...[truncated 1884 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/auth.ts:292
Finding

Manual OAuth Error Handling Can Log Authorization Codes

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Rogue AgentSelf-Modification, Session Persistence
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill clearly instructs the agent/user to invoke a local CLI that uses shell execution and network access, yet the skill declares no permissions or trust boundaries. This mismatch increases the chance that an agent will perform authenticated remote state changes without explicit capability disclosure or user approval.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill documents abandon and batch-abandon as normal operations but does not prominently warn that they irreversibly modify remote task state in the user's TickTick account. In an agent context, this can lead to unintended bulk changes if the model acts on ambiguous instructions or stale task IDs.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
84% confidence
Finding

The skill stores OAuth client credentials and long-lived tokens in a plaintext file under the user's home directory, creating persistent authenticated session material on disk. If the host is multi-user, compromised, or backups/logs expose that file, an attacker could reuse the tokens or secrets to access and modify the user's TickTick data.

Content

Scanner excerpt · SKILL.md (reported line 15)May include surrounding context.

md
### 1. Register a TickTick Developer App

1. Go to [TickTick Developer Center](https://developer.ticktick.com/manage)
2. Create a new application
3. Set the redirect URI to `http://localhost:8080`
4. Note your `Client ID` and `Client Secret`

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