Back to skill

Security audit

Restart Task Recovery

Security checks for vulnerabilities and agentic risk

Overview

The skill has a legitimate restart-recovery purpose, but saved task text can become automatic resume messages sent to other sessions, so it needs review before use.

Review this skill before installing or using it in workspaces with sensitive tasks. Treat checkpoints as untrusted data, inspect generated recovery plans before sending them, avoid automatic sessions_send for free-form recovered messages, and store checkpoint/temp files in private locations with restrictive permissions.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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)

T01 · Skill Instruction Hijacking

Error
Location
scripts/build_checkpoint.py:23
Finding
Untrusted checkpoint content can inject automatically dispatched resume instructions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/build_checkpoint.py:23-42`, `scripts/generate_resume_plan.py:17-27`, `scripts/recover_from_latest_checkpoint.py:17-27`, `scripts/pre_resume_verify.py:22-35`, `SKILL.md:115-118, 129-139, 156-159` **Vulnerability Type**: Prompt injection through unsafe serialization and automatic message dispatch **Risk Level**: High ### Vulnerable Code `scripts/build_checkpoint.py:23-42`: ```python for s in sessions: key = s.get("sessionKey", "unknown") agent = s.get("agentId", "unknown") goal = s.get("goal", "(fill)") done = s.get("lastDone", "(fill)") nxt = s.get("nextStep", "(fill)") blockers = s.get("blockers", "none") lines.append(f"## {key}") lines.append(f"- Agent: {agent}") lines.append(f"- Goal: {goal}") lines.append(f"- Last done: {done}") lines.append(f"- Next: {nxt}") lines.append(f"- Blockers: {blockers}") lines.append( f"- Resume message: Continue where you left off. Last completed: {done}. Next: {nxt}." ) lines.append("") ``` `scripts/generate_resume_plan.py:17-27`: ```python fields = {} for ln in lines[1:]: m = re.match(r"-\s*([^:]+):\s*(.*)", ln.strip()) if m: fields[m.group(1).strip()] = m.group(2).strip() msg = fields.get("Resume message") or ( f"Continue where you left off. Last completed: {fields.get('Last done', '(unknown)')}. Next: {fields.get('Next', '(unknown)')}." ) items.append( { "sessionKey": session_key, "agent": fields.get("Agent", "unknown"), "goal": fields.get("Goal", ""), "resumeMessage": msg, } ) ``` `scripts/recover_from_latest_checkpoint.py:17-27`: ```python fields = {} for ln in lines[1:]: m = re.match(r"-\s*([^:]+):\s*(.*)", ln.strip()) if m: fields[m.group(1).strip()] = m.group(2).strip() resume = fields.get("Resume message") or ( f"Continue where you left off. Last completed: {fields.get('Last done', '(unknown)')}. Next: {fi ...[truncated 3593 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the Markdown checkpoint as the canonical data format with a strictly defined JSON structure. 2. Validate every input field: - Require strings of bounded length. - Reject control characters and embedded newlines where they are not explicitly needed. - Validate session keys against the platform's expected session-key syntax. 3. Never accept a serialized `Resume message` as authoritative. Construct the message from validated, structured fields at send time. 4. Treat checkpoint data and prior session history as untrusted content, not agent instructions. 5. Use a fixed system-authored resume instruction and attach historical fields inside clearly delimited data sections. 6. Replace the keyword denylist with an allowlisted typed-action model. Free-form recovered instructions should require manual confirmation. 7. Bind recovery actions to the current session inventory and verify that each target session is expected before sending. 8. Add security tests covering embedded newlines, forged Markdown fields, duplicate fields, disclosure requests, tool-use instructions, Unicode obfuscation, and destructive-operation synonyms. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/smoke_test.sh:35
Finding
Predictable shared temporary files expose and permit tampering with recovery plans<![CDATA[ ## Vulnerability Details **File Location**: `scripts/smoke_test.sh:35-39, 51-52`; `SKILL.md:82, 108, 128, 149` **Vulnerability Type**: Unsafe temporary-file handling **Risk Level**: Medium ### Vulnerable Code `scripts/smoke_test.sh:35-39`: ```bash cat "$WS/tmp/session-snapshot.json" | python3 "$ROOT/scripts/build_checkpoint.py" "$CP" >/dev/null python3 "$ROOT/scripts/recover_from_latest_checkpoint.py" "$CP" > "$TMPDIR/recover-actions.json" python3 "$ROOT/scripts/pre_resume_verify.py" "$TMPDIR/recover-actions.json" "$TMPDIR/recover-verified.json" >/dev/null python3 "$ROOT/scripts/execute_verified_recovery.py" "$TMPDIR/recover-verified.json" > "$TMPDIR/recover-exec.json" ``` `scripts/smoke_test.sh:51-52`: ```bash p=os.environ.get('TMPDIR','/tmp') with open(f"{p}/recover-exec.json","r",encoding='utf-8') as f: ``` The documented workflow also uses fixed paths: ```bash python3 scripts/recover_from_latest_checkpoint.py > /tmp/recover-actions.json python3 scripts/pre_resume_verify.py /tmp/recover-actions.json /tmp/recover-verified.json python3 scripts/execute_verified_recovery.py /tmp/recover-verified.json > /tmp/recover-exec.json ``` ### Technical Analysis The workflow stores intermediate action plans at predictable names under `/tmp` or a caller-controlled `TMPDIR`. These files contain session identifiers and free-form resume instructions. Predictable shared filenames create several security problems: - Concurrent executions can overwrite or consume each other's files. - Another local process with sufficient access can replace a plan between generation and verification or execution. - File confidentiality depends on the process umask and temporary-directory permissions. - Shell redirection and ordinary file writes do not explicitly reject symbolic links. - No private temporary directory is created, and no cleanup handler removes sensitive artifacts. The final exploitability of symbolic-link attacks depends on operating-system protections and the ...[truncated 1364 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a unique private directory for each run: ```bash WORKDIR="$(mktemp -d)" chmod 700 "$WORKDIR" trap 'rm -rf "$WORKDIR"' EXIT ``` 2. Store every intermediate file under that directory rather than using fixed `/tmp` names. 3. Set a restrictive umask before writing session-related data: ```bash umask 077 ``` 4. Create output files atomically and avoid following symbolic links where supported. 5. Verify file ownership, regular-file status, and permissions before reading an intermediate plan. 6. Add a workflow identifier or cryptographic integrity binding between generated, verified, and executable plans. 7. Validate the complete verified-plan schema in `execute_verified_recovery.py`; do not trust arbitrary input merely because it contains `decision=send`. 8. Update all examples in `SKILL.md` to demonstrate secure temporary-directory creation and automatic cleanup. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill instructs use of file reads/writes and local script execution workflows but does not declare any explicit tool scope or allowed-tools boundary. That omission increases the chance the skill will run with broader-than-necessary capabilities, making misuse or accidental access to local files and environment data more likely in a restart/recovery context.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script serializes stdin-provided session data directly into a persistent checkpoint file, and the fields included (goal, lastDone, nextStep, blockers, resume message) can easily contain sensitive task context, secrets, internal paths, or user data. In a restart-recovery skill, persisting in-progress multi-agent state is expected, but doing so without minimization, redaction, or an explicit warning increases the chance of unintended sensitive data retention on disk.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
These lines invoke several subordinate scripts and include an 'execute_verified_recovery' step, which may perform consequential actions, but the shell file provides no comments or pre-execution notice describing that subprocess-driven recovery logic will run. The final summary output does not satisfy the requirement for advance disclosure of safety-relevant subprocess execution.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The example note is written only in Chinese: “配置已更新并重启;将按 checkpoint 恢复中断任务。” This introduces a locale-specific instruction in the skill guidance without offering a language choice or explaining that the workflow is intended for a Chinese-only environment.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
This markdown file contains user-facing template text in Chinese for status updates and manual confirmations. Because the file does not indicate that the skill is region-specific or that the user can choose the language, it may violate language/locale policy requirements.

Missing User Warnings

Low
Confidence
89% confidence
Finding
The script writes recovery state and generated artifacts into shared workspace and temporary locations such as "$WS/tmp", "$WS/memory/restart-checkpoints", and "$TMPDIR" without creating isolated, permission-restricted files. If those paths are writable or observable by other local users/processes, sensitive session state could be disclosed or files could be replaced via symlink or race attacks, causing checkpoint corruption or unsafe downstream processing.

Static analysis

No suspicious patterns detected.