Back to skill

Security audit

Task Sync

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real task-sync skill, but it can automatically delete real Google Tasks and TickTick data with insufficient safeguards.

Review carefully before installing. Use only dedicated test accounts or empty test lists until safeguards are added, do not enable cron on important task data, restrict token file permissions, pin the TickTick API endpoint to the official host, and add dry-run or confirmation controls before any delete propagation.

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

T09 · Insecure Skill Coding Practices

Error
Location
utils/ticktick_api.py:11
Finding

Configurable TickTick API Base Can Exfiltrate Bearer Tokens and Task Data

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
sync.py:274
Finding

Ambiguous API Errors Are Interpreted as Remote Task Deletions

Content
View full analysis
%d: %s", method, endpoint, resp.status_code, resp.text[:200] ) return None except requests.RequestException as e: log.error("TickTick request error: %s", e) return None # utils/ticktick_api.py:65-68 def get_task(self, project_id, task_id): """Get a single task by ID. Returns task dict or None if deleted/not found.""" return self._request(f"/project/{project_id}/task/{task_id}") ``` ```python # sync.py:274-288 tt_task = self.ticktick.get_task(t_proj["id"], tid) if tt_task: if not g_done: log.info("Completed in TickTick: %s", g["title"]) self.google.update_task( g_list["id"], gid, status="completed" ) self.stats["completed"] += 1 else: if not g_done: log.info( "Deleted in TickTick, deleting from Google: %s", g["title"], ) self.google.delete_task(g_list["id"], gid) del task_db[gid] self.stats["completed"] += 1 ``` ```python # sync.py:327-337 known_gid = rev_idx.get(tid) if known_gid: log.info("Google partner gone, deleting: %s", t["title"]) self.ticktick.delete_task(t_proj["id"], tid) task_db. ...[truncated 1857 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
sync.py:132
Finding

TickTick Project Enumeration Failure Can Delete All Mapped Google Lists

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
sync.py:408
Finding

Smart-List Cleanup Deletes Unrelated Tasks from Existing Google Lists

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/setup_google_tasks.py:87
Finding

OAuth Tokens and Client Secrets Are Stored Without Enforced Restrictive Permissions

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
README.md:78
Finding

Unpinned Third-Party Dependencies Create a Mutable Supply-Chain Risk

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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description covers a broad synchronization skill between TickTick and Google Tasks, with sync logic, mapping, exports, and troubleshooting. The supplied code chunk does only one narrow setup function: TickTick OAuth authorization and token storage. While OAuth setup is mentioned in the description as one possible use case, the code does not implement the primary declared behavior of synchronization or any Google-side functionality. This is therefore a material description-behavior mismatch rather than a supporting partial implementation of the full declared skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

This test suite performs live creation, completion, and deletion-like lifecycle changes against real Google Tasks and TickTick data, with no guardrails to ensure it is operating on a dedicated test account or sandbox. In the context of an agent skill, that is dangerous because accidental execution can modify or destroy a user's real task data at scale.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script deletes a Google task list programmatically without confirmation or robust ownership checks. If the wrong list ID is used or the test runs against a real account, this can permanently remove user-organized data and cause broader data loss than individual task completion.

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 · README.md (reported line 87)May include surrounding context.

md
SCOPES = ["https://www.googleapis.com/auth/tasks"]
BASE_DIR = Path(__file__).resolve().parent.parent
DEFAULT_CONFIG_FILE = BASE_DIR / "config.json"
DEFAULT_CREDENTIALS_FILE = BASE_DIR / "config" / "google_credentials.json"
DEFAULT_TOKEN_FILE = BASE_DIR / "data" / "google_token.json"

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/setup_google_tasks.py (reported line 15)May include surrounding context.

python
SCOPES = ["https://www.googleapis.com/auth/tasks"]
BASE_DIR = Path(__file__).resolve().parent.parent
DEFAULT_CONFIG_FILE = BASE_DIR / "config.json"
DEFAULT_CREDENTIALS_FILE = BASE_DIR / "config" / "google_credentials.json"
DEFAULT_TOKEN_FILE = BASE_DIR / "data" / "google_token.json"

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/setup_ticktick.py (reported line 95)May include surrounding context.

python
"scope": "tasks:read tasks:write",
    }

    print("\nRequesting access token...")
    response = requests.post(token_url, data=data, timeout=30)

    if response.status_code == 200:

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/setup_ticktick.py (reported line 100)May include surrounding context.

python
if response.status_code == 200:
        token_data = response.json()
        print("Access token received.")
        return token_data

    print(f"Failed to get token ({response.status_code}): {response.text}")

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 · README.md (reported line 111)May include surrounding context.

"ticktick_token": "/path/to/ticktick/token.json", "sync_db": "/path/to/sync_db.json", "sync_log": "/path/to/sync_log.json", "ticktick_api_base": "https://api.ticktick.com/open/v1" }

text

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README instructs users to run an end-to-end test suite against live Google Tasks and TickTick APIs but does not explicitly warn that the tests can create, modify, complete, or delete real user task data. In a bidirectional sync skill, this omission is risky because users may run tests against production accounts and unintentionally alter or lose task state across both services.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill invokes Python scripts, performs OAuth setup, and references cron, logs, config files, and external APIs, yet it declares no explicit tool scope or permissions boundaries. In an agent environment, this can cause over-broad access to shell, network, environment variables, and file writes without clear user-visible constraints, increasing the chance of unsafe execution or secret exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The setup instructions direct users to perform OAuth flows, configure token paths, and run synchronization with third-party services, but they do not explicitly warn that access tokens will be stored locally and that task titles, notes, dates, and completion data will be transmitted externally. This weakens informed consent and can lead to accidental exposure of sensitive task content or insecure handling of credential files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This Python file reads Google and TickTick tokens from configuration and immediately initializes API clients that will act on remote task data. While the module docstring says it is an E2E sync test, there is no explicit warning in the file that credentials are being used and that task data will be sent to third-party services.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The helper runs sync.py via subprocess, and that sync operation can modify tasks across Google Tasks and TickTick. Although there is a console message saying "Running sync...", it does not clearly warn that the subprocess may change remote user data as part of the test.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · e2e_test.py (reported line 63)May include surrounding context.

python
def run_sync():
    """Run sync.py and return output."""
    result = subprocess.run(
        [PYTHON_BIN, SYNC_SCRIPT],
        capture_output=True, text=True, cwd=BASE_DIR, timeout=120,
    )

Tainted flow: 'PYTHON_BIN' from os.environ.get (line 17, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
93% confidence
Finding

The executable used by subprocess.run is taken from the PYTHON_BIN environment variable without validation. An attacker who can influence the environment could cause the test to execute an arbitrary binary instead of Python, leading to unintended code execution with access to the same local files and API tokens used by the test.

Content

Scanner excerpt · e2e_test.py (reported line 63)May include surrounding context.

python
def run_sync():
    """Run sync.py and return output."""
    result = subprocess.run(
        [PYTHON_BIN, SYNC_SCRIPT],
        capture_output=True, text=True, cwd=BASE_DIR, timeout=120,
    )

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code removes an existing token file before proceeding and later writes a replacement token file, which is a safety-relevant file modification. Although there are print statements describing the paths, the script does not ask the user to confirm the deletion or overwrite before performing it.

Content

No source excerpt is available for this finding.

Tainted flow: 'data' from input (line 86, user input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/setup_ticktick.py (reported line 96)May include surrounding context.

python
}

    print("\nRequesting access token...")
    response = requests.post(token_url, data=data, timeout=30)

    if response.status_code == 200:
        token_data = response.json()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The sync logic automatically deletes Google lists, Google tasks, and TickTick tasks when it infers the counterpart was deleted or is missing, with no dry-run, confirmation gate, conflict review, or safety threshold. In a bidirectional sync skill that manages user task data, mistaken mappings, transient API errors, stale caches, or inconsistent remote state can cause irreversible data loss across both services.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.