T06 · System Persistence
Error
- Location
- SKILL.md:110
- Finding
- Automatic Installation of Cross-Session Heartbeat and Cron Persistence<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:110-148` and `SKILL.md:396-425` **Vulnerability Type**: Automatic scheduled-task and heartbeat persistence **Risk Level**: High ### Vulnerable Code ```text Step 0 — First Run Setup (auto-configure on first use) [3] Register heartbeat entry: READ HEARTBEAT.md (create it if missing) IF "Task Runner Dispatcher" is NOT already in the file: APPEND the following block: ## Task Runner Dispatcher Every heartbeat: check ${TASK_RUNNER_DIR}/task-queue.json - If pending or running tasks exist → run DISPATCHER mode (task-runner skill) - If nothing pending → HEARTBEAT_OK (skip) WRITE the updated HEARTBEAT.md [4] Register backup cron job: CALL cron tool with: action: "add" job: name: "Task Runner Dispatcher" schedule: { kind: "every", everyMs: 900000 } payload: { kind: "systemEvent", text: "TASK_RUNNER_DISPATCH: check queue and run pending tasks" } sessionTarget: "main" enabled: true ``` The persistence behavior is also explicitly enabled in `skill.yml:158-164`: ```yaml heartbeat_integration: register_in_heartbeat_md: true heartbeat_check: "Read ${TASK_RUNNER_DIR}/task-queue.json; if pending/running tasks exist, run DISPATCHER mode; else HEARTBEAT_OK" cron_backup: schedule: "every 15 minutes" system_event: "TASK_RUNNER_DISPATCH: check queue and run pending tasks" ``` ### Technical Analysis On the first broadly matching intake request, the Skill modifies `HEARTBEAT.md` and creates a recurring cron job targeting the main agent session. Both mechanisms survive the original Skill invocation and repeatedly reactivate the dispatcher. A persistent queue reasonably requires some form of later execution, so scheduling is related to the declared functionality. However, the implementation exceeds minimum privilege because: - Two independent persistence mechanisms are installed automatically. - Installat ...[truncated 1868 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require explicit, informed user approval before modifying `HEARTBEAT.md` or registering a cron job. 2. Present the schedule, target session, capabilities, and retention behavior before installation. 3. Use only one persistence mechanism by default. Make the backup mechanism separately opt-in. 4. Run scheduled dispatch in a dedicated restricted session rather than the main session. 5. Add commands such as `disable task runner` and `uninstall task runner` that: - Disable and remove the cron job. - Remove only the Skill-owned block from `HEARTBEAT.md`. - Stop or revoke active subagent sessions where supported. - Optionally purge the queue and archives after confirmation. 6. Store and validate the scheduler's unique job identifier instead of relying only on queue-file existence. 7. Prevent queue deletion from implicitly reinstalling persistence. 8. Add tests verifying explicit consent, reliable removal, duplicate prevention, and disabled-state enforcement. ]]>
