Back to skill

Security audit

Taskboard Cli

Security checks for vulnerabilities and agentic risk

Overview

The core taskboard script is local, but the skill also tells agents to act on free-form stored hook instructions and includes under-disclosed GitHub/Discord integration guidance.

Review before installing. The local taskboard script is not malware and does not itself call the network, but do not let agents automatically execute hook text from tasks. Treat hook values, task comments, and task titles as untrusted data. Only enable GitHub or Discord integrations with explicit user approval, least-privilege tokens, secret storage outside source control, and confirmation before posting messages or mutating remote issues.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (1)

T01 · Skill Instruction Hijacking

Warning
Location
scripts/taskboard.py:302
Finding
Stored Hook Instructions Can Hijack Agent Tool Actions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/taskboard.py:260-269, 302-305`; related trust guidance in `SKILL.md:78` **Vulnerability Type**: Stored instruction injection through unvalidated task hooks **Risk Level**: Medium ### Vulnerable Code ```python if getattr(args, "on_ack", None) is not None: old = task["on_ack"] if "on_ack" in task.keys() else None changes.append(("on_ack", old, args.on_ack)) updates.append("on_ack = ?") params.append(args.on_ack) if getattr(args, "on_done", None) is not None: old = task["on_done"] if "on_done" in task.keys() else None changes.append(("on_done", old, args.on_done)) updates.append("on_done = ?") params.append(args.on_done) ``` ```python # Refresh and emit hooks task = db.execute("SELECT * FROM tasks WHERE id = ?", (args.id,)).fetchone() if args.status == "in_progress" and task["on_ack"]: print(f"\n🔔 ON_ACK: {task['on_ack']}") if args.status == "done" and task["on_done"]: print(f"\n🔔 ON_DONE: {task['on_done']}") ``` The associated operational guidance states: ```text The agent reads these lines and decides how to act (send a message, spawn a session, create a task, etc.). ``` ### Technical Analysis The `--on-ack` and `--on-done` arguments accept unrestricted text. That text is persisted in SQLite and later printed using a trusted-looking `ON_ACK` or `ON_DONE` marker. No parser, action allowlist, destination validation, authorization check, or separation between data and instructions is applied before emission. Parameterized SQL prevents SQL injection, but it does not address instruction injection. The security boundary is crossed when an AI agent or wrapper interprets the emitted value as an instruction and invokes privileged messaging, session, or task-management tools. Because the value is stored, the malicious instruction may execute later when another operator changes the task status. The Python CLI itself does not execute the hook as shell code and ...[truncated 1599 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace free-form hook strings with a structured schema containing explicit fields such as `action`, `destination`, and `message`. 2. Allowlist supported action types and reject unknown actions rather than passing them to an agent for interpretation. 3. Validate destination identifiers against an administrator-controlled allowlist. 4. Treat message bodies as inert content and explicitly prohibit consumers from interpreting them as secondary instructions. 5. Require explicit user confirmation before external messaging, session creation, or any other consequential tool invocation. 6. Record the hook creator and enforce authorization checks when hooks are created, modified, and triggered. 7. Escape or encode control characters and multiline content before emitting machine-readable output. 8. Prefer a versioned JSON event format over trusted-looking natural-language instructions, for example: ```json { "event": "task_done", "task_id": 5, "action": "notify", "destination": "approved-channel-id", "message": "Task completed" } ``` 9. Document that hook fields are untrusted data and that integrations must independently validate every requested action. 10. If automation is required, run the consumer with narrowly scoped tool permissions and deny session creation or arbitrary destinations by default. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (17)

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
## Hooks (Cross-Agent Orchestration)

Hooks fire when task status changes. They print instructions to stdout for the calling agent to execute — no auto-execution, no network calls.

```bash
# When task is started (ack'd), print a notification instruction
Confidence
90% confidence
Finding
The skill defines a mechanism where task fields can contain attacker-controlled hook strings that are printed as actionable instructions for the calling agent to execute. Even without direct auto-execution, this creates a prompt-injection / command-confusion channel: malicious task content can cause downstream agents to send messages, spawn sessions, or perform other sensitive actions if they trust stdout instructions.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The reference guide expands a stated local-only, no-credentials SQLite taskboard into a networked GitHub integration that requires a repo-scoped personal access token and optional webhook/agent endpoint handling. This materially changes the trust boundary and data flow of the skill, creating opportunities for unintended external transmission of task content and misuse of repository privileges if an agent implements the guide as written.

Credential Access

High
Category
Privilege Escalation
Content
## Prerequisites

- A GitHub Personal Access Token with `repo` scope
- Set as environment variable: `export GITHUB_TOKEN=ghp_...`
- Recommended: use a dedicated machine/service token, not your personal token
Confidence
96% confidence
Finding
The guide directs use of a GitHub Personal Access Token with broad repo scope and environment-variable storage, introducing credential acquisition and handling into a skill that claims no credentials are needed. Broad tokens materially increase blast radius if copied, logged, exposed in shell history, or misused by an agent implementation following this reference.

Intent-Code Divergence

High
Confidence
96% confidence
Finding
The skill metadata says status-change hooks emit instructions but do not auto-execute, yet the reference guide tells the agent that when sync is enabled it should perform GitHub API operations on task events. That contradiction can cause an agent or integrator to implement automatic remote side effects on local task actions, leading to unexpected issue creation, comment posting, assignment changes, and state transitions in external systems.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
"""TaskBoard CLI — lightweight SQLite task coordination for multi-agent workflows.

No network calls, no environment variables, no external dependencies.
Hooks print instructions to stdout for the agent to execute.
"""

import argparse
Confidence
94% confidence
Finding
The skill explicitly supports storing and later printing hook text ('on_ack'/'on_done') as instructions for an agent to execute, and those values are fully user-controlled via CLI arguments and database contents. Even though the script does not itself execute code, emitting untrusted instruction text into an agent workflow creates a prompt-injection / instruction-smuggling path where malicious task data can cause downstream agents to perform unintended actions.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
---
name: taskboard-cli
version: 3.0.1
description: "Lightweight task management CLI for multi-agent workflows. SQLite backend, no external dependencies or credentials. Status-change hooks emit agent instructions (message, session) but do not auto-execute. Use when managing tasks across agents, tracking work status, assigning tasks, generating board summaries, or orchestrating cross-agent handoffs. Triggers on \"create task\", \"task board\", \"taskboard\", \"list tasks\", \"assign task\", \"board summary\", \"project tasks\"."
---

# Taskboard CLI
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The manifest description says the skill triggers on phrases such as "create task", "list tasks", and "project tasks". These are generic phrases that can occur in normal conversation or in contexts unrelated to this specific taskboard CLI, and the file does not provide exclusion conditions or tighter activation scope.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The document instructs users or agents to provision and use a GitHub token despite the skill metadata claiming no external dependencies or credentials. Even if presented as reference material, this normalizes credential handling and remote synchronization outside the declared scope, increasing the chance that sensitive task data is sent externally under a misleading local-only trust model.

External Transmission

Medium
Category
Data Exfiltration
Content
### Create Issue
```bash
curl -X POST https://api.github.com/repos/OWNER/REPO/issues \
  -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github.v3+json" \
  -d '{
Confidence
90% confidence
Finding
The documented endpoint to api.github.com indicates the skill may communicate with an external third-party service. In context, this is not inherently malicious, but it conflicts with the local-only positioning and increases risk of unintended disclosure of task metadata and repository operations if implemented automatically by an agent.

External Transmission

Medium
Category
Data Exfiltration
Content
### Create Issue
```bash
curl -X POST https://api.github.com/repos/OWNER/REPO/issues \
  -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github.v3+json" \
  -d '{
Confidence
90% confidence
Finding
The documented endpoint to api.github.com indicates the skill may communicate with an external third-party service. In context, this is not inherently malicious, but it conflicts with the local-only positioning and increases risk of unintended disclosure of task metadata and repository operations if implemented automatically by an agent.

External Transmission

Medium
Category
Data Exfiltration
Content
### Update Issue Status
```bash
# Update labels
curl -X PATCH https://api.github.com/repos/OWNER/REPO/issues/ISSUE_NUMBER \
  -H "Authorization: token $GITHUB_TOKEN" \
  -d '{"labels": ["status:in-progress", "backend"]}'
Confidence
90% confidence
Finding
Updating issue labels over the GitHub API is another external write operation tied to local task status changes. If an agent interprets this as automatic behavior, local workflow events could silently mutate remote project state and leak status information beyond the user’s expectations.

External Transmission

Medium
Category
Data Exfiltration
Content
-d '{"labels": ["status:in-progress", "backend"]}'

# Close issue (when done)
curl -X PATCH https://api.github.com/repos/OWNER/REPO/issues/ISSUE_NUMBER \
  -H "Authorization: token $GITHUB_TOKEN" \
  -d '{"state": "closed"}'
```
Confidence
90% confidence
Finding
Closing issues via the GitHub API creates externally visible workflow changes based on local actions. In the context of a local taskboard skill, this broadens impact from data disclosure to integrity risks, because an agent could prematurely close or reopen remote issues without strong confirmation controls.

External Transmission

Medium
Category
Data Exfiltration
Content
### Add Comment
```bash
curl -X POST https://api.github.com/repos/OWNER/REPO/issues/ISSUE_NUMBER/comments \
  -H "Authorization: token $GITHUB_TOKEN" \
  -d '{"body": "PR #42 ready for review"}'
```
Confidence
89% confidence
Finding
Posting comments to GitHub transmits notes such as PR references or task context to an external service. Because notes may contain internal project details, this can expose sensitive operational information when users believe they are using a local SQLite task tracker.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The documentation states the task system is file-based and stored in `taskboard.json`, which directly conflicts with the manifest description claiming a SQLite backend. This kind of spec drift is dangerous because agents or operators may make incorrect trust and operational assumptions about storage, locking, concurrency, backup behavior, and data exposure, leading to misuse or insecure deployment.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The file documents Discord notifications, cron-driven summaries, and channel posting behavior even though the skill metadata says there are no external dependencies or credentials and that hooks emit instructions but do not auto-execute. This mismatch can normalize external messaging behavior and lead users or downstream agents to wire the skill into networked notification flows that exceed its declared local-only scope, increasing the risk of unintended data disclosure or unauthorized integrations.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation includes a configuration example containing secret-bearing fields such as a Discord webhook URL and a hooks token, but it does not clearly warn readers that these values are credentials that must be protected and never committed to source control. Even though the shown values are placeholders, users commonly copy example configs verbatim, which can lead to real secrets being stored insecurely, leaked in repos, or exposed in logs.

Missing User Warnings

Low
Confidence
83% confidence
Finding
The guide says the agent can add GitHub linkage fields directly to taskboard.json without warning about local file modification. While lower severity than credential or network issues, silent persistence changes can surprise users, alter source-controlled files, or create integrity issues if performed automatically by an agent.

Static analysis

No suspicious patterns detected.