Back to skill

Security audit

TaskMaster - AI Cost Optimizer

Security checks for vulnerabilities and agentic risk

Overview

TaskMaster is mostly coherent as a task-delegation skill, but it under-discloses sensitive local logging and has budget-control weaknesses that users should review before installing.

Review this skill before installing if you plan to delegate sensitive work or rely on its spending limits. Avoid placing credentials, customer data, proprietary code, or confidential incident details in task descriptions unless you are comfortable with them being sent to sub-agents and potentially written to a local plaintext cost log. Treat the budget feature as advisory unless the implementation is fixed to reserve costs atomically and avoid duplicate or parallel overrun.

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/delegate_task.py:287
Finding

Unredacted Task Descriptions Persisted in Plaintext Cost Logs

Content
View full analysis

Vulnerability Details

File Location: scripts/delegate_task.py, lines 287-311
Vulnerability Type: Plaintext storage of potentially sensitive user-controlled data
Risk Level: Medium

Vulnerable Code

python
def log_cost(self, task_id: str, result: TaskResult):
    """Log actual vs estimated costs to tracking file."""
    log_entry = {
        "timestamp": time.time(),
        "task_id": task_id,
        "description": self.tasks[task_id].description,
        "model": result.model_used.value,
        "estimated_cost": self.tasks[task_id].estimated_cost,
        "actual_cost": result.actual_cost,
        "accuracy": result.actual_cost / self.tasks[task_id].estimated_cost if self.tasks[task_id].estimated_cost > 0 else 1.0
    }
    
    try:
        # Read existing log
        try:
            with open("taskmaster-costs.json", "r") as f:
                costs = json.load(f)
        except FileNotFoundError:
            costs = []
        
        # Append new entry
        costs.append(log_entry)
        
        # Write back
        with open("taskmaster-costs.json", "w") as f:
            json.dump(costs, f, indent=2)

Technical Analysis

The cost logger stores the full task description in taskmaster-costs.json. Task descriptions are arbitrary user-controlled content and may include proprietary source code, customer records, incident details, internal URLs, access tokens, or other confidential information.

The data is written without redaction, encryption, an explicit user opt-in, retention controls, or restrictive file permissions. The path is relative to the process working directory, making its location dependent on how the Skill is launched. The resulting permissions also depend on the process umask.

This storage exceeds the minimum data required for cost tracking. Cost accounting only requires identifiers, model information, token counts, and monetary t ...[truncated 1145 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the description field from cost logs by default. Store only a non-sensitive task identifier, model name, token counts, timestamp, and cost totals.
  2. If descriptions are required for diagnostics, require explicit opt-in and provide a prominent warning that task content will be retained.
  3. Add configurable redaction for credentials, authorization headers, URL query tokens, email addresses, and other sensitive patterns.
  4. Store logs in a dedicated application data directory rather than the current working directory.
  5. Create the log with owner-only permissions, such as mode 0600, and verify existing file permissions before appending.
  6. Use atomic file replacement to prevent partial writes and apply appropriate locking for concurrent writers.
  7. Define retention limits and provide a deletion mechanism.
  8. Add taskmaster-costs.json to source-control ignore rules where appropriate.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/delegate_task.py:177
Finding

Non-Atomic Budget Enforcement Allows Aggregate Spending Limit Bypass

Content
View full analysis

Vulnerability Details

File Location: scripts/delegate_task.py, lines 177-190
Related Locations: scripts/delegate_task.py, lines 215-247 and 317-330
Vulnerability Type: State-management and budget-enforcement flaw
Risk Level: Medium

Vulnerable Code

python
def can_execute_task(self, task_id: str) -> Tuple[bool, str]:
    """Check if task can be executed (budget + dependencies)."""
    task = self.tasks[task_id]
    
    # Check budget
    if self.spent_budget + task.estimated_cost > self.total_budget:
        return False, f"Would exceed budget: ${task.estimated_cost:.2f} + ${self.spent_budget:.2f} > ${self.total_budget:.2f}"
    
    # Check dependencies
    for dep_id in task.dependencies:
        if dep_id not in self.results or not self.results[dep_id].success:
            return False, f"Dependency not completed: {dep_id}"
            
    return True, "Ready to execute"

The execution method checks the budget but does not reserve cost or persist the result internally:

python
def execute_task(self, task_id: str) -> TaskResult:
    """Execute a task via OpenClaw sessions_spawn with real token tracking."""
    task = self.tasks[task_id]
    
    can_execute, reason = self.can_execute_task(task_id)
    if not can_execute:
        return TaskResult(
            task_id=task_id,
            success=False,
            output="",
            actual_cost=0.0,
            execution_time=0.0,
            model_used=task.model,
            error_message=reason
        )

    # ...

    return TaskResult(
        task_id=task_id,
        success=True,
        output=f"Ready to spawn: {spawn_command}",
        actual_cost=task.estimated_cost,
        execution_time=0.0,
        model_used=task.model
    )

Actual-cost reconciliation assumes that external code has already inserted the result and charged the estimate:

python

...[truncated 2841 chars]
Remediation
View remediation

Remediation Suggestions

  1. Make budget validation and reservation a single atomic operation.
  2. Reserve task.estimated_cost inside execute_task() before returning spawn arguments.
  3. Add explicit task states such as pending, reserved, running, completed, and failed.
  4. Reject duplicate execution when a task is already reserved, active, or completed.
  5. Store the TaskResult and reservation internally rather than requiring callers to mutate results and spent_budget.
  6. Reconcile the reserved estimate against actual cost on completion. Release the reservation on cancellation or confirmed spawn failure.
  7. Protect state changes with a lock for in-process parallel execution or use a transactional persistent store across processes.
  8. Before accepting an actual cost above the reservation, check the remaining budget and apply a documented policy such as stopping additional tasks and alerting the user.
  9. Add tests covering parallel reservations, duplicate task execution, failed spawns, missing results, cancellation, and actual costs above estimates.
  10. Clearly distinguish between cost estimation and enforceable provider-side spending controls; where available, also configure provider-level quotas.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/delegate_task.py (reported line 240)May include surrounding context.

python
print(f"Ready to spawn with:")
        print(spawn_command)
        
        # For now, return instruction for manual execution
        # TODO: Integrate with actual OpenClaw sessions_spawn API
        return TaskResult(
            task_id=task_id,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The README explicitly instructs users to spawn delegated sub-agents and read a local cost-history file, but it does not warn that delegated tasks may execute with the user's tool permissions or that local usage data may be persisted and exposed. In an agent skill whose core purpose is task delegation, omission of these trust-boundary and data-handling warnings can lead users to authorize actions or expose local metadata without understanding the risks.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises orchestration behavior and references a delegation script, while the manifest declares no explicit tool scope or permissions. That mismatch can cause the runtime to grant or infer broader file access than the user expects, increasing the chance that delegated tasks read or write local project data without clear authorization boundaries.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill promotes spawning isolated sub-agents and parallel execution but does not warn users that these agents may autonomously act on delegated tasks. This reduces informed consent and can lead users to provide sensitive or high-impact work items without understanding that multiple agents may process them concurrently.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The implementation notes state that sub-agents receive isolated sessions, but the documentation does not clearly disclose that task contents and project data may be passed to those sub-agents during orchestration. This creates a data-handling transparency issue: users may unintentionally expose confidential requirements, code, or documents to additional processing contexts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code persists full task descriptions to taskmaster-costs.json without consent, redaction, or minimization. Task descriptions may contain sensitive prompts, proprietary project details, credentials, file names, or user data, so writing them to a local tracking file creates an unnecessary data-retention and privacy exposure.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.