T09 · Insecure Skill Coding Practices
- Location
scripts/init_planner.py:27- Finding
Arbitrary Recursive Directory Deletion Through the Force Option
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The planner is coherent, but it needs review because one setup option can delete any chosen folder and optional calendar sync depends on an unpinned third-party tool.
Install only if you are comfortable with a local planner that writes files in your workspace. Run init without --force unless you have verified the resolved target is only a disposable planner directory. Prefer ICS export unless you trust the gogcli installation source; if using Google Calendar sync, use a dedicated calendar, review dry-run output, and keep calendar.write_enabled false until you deliberately apply changes.
scripts/init_planner.py:27Arbitrary Recursive Directory Deletion Through the Force Option
SKILL.md:6Unpinned Third-Party Calendar CLI Installation Creates a Supply-Chain Risk
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.
out_path = Path(args.out).expanduser().resolve() if args.out else (planner_dir / "weeks" / f"{week_id}.toml")
if out_path.exists():
raise SystemExit(f"Refusing to overwrite existing file: {out_path}")
if not runbook_path.exists():
raise SystemExit(f"Runbook not found: {runbook_path}")
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.
out_path = Path(args.out).expanduser().resolve() if args.out else (planner_dir / "weeks" / f"{week_id}.toml")
if out_path.exists():
raise SystemExit(f"Refusing to overwrite existing file: {out_path}")
if not runbook_path.exists():
raise SystemExit(f"Runbook not found: {runbook_path}")
The trigger says the mode applies when 'building, writing, coding, analysis, or any task that benefits from uninterrupted focus,' which overlaps with many common activities and adds an open-ended catch-all condition. The file does not provide specific scope limits, explicit trigger phrases, or negative examples to clarify when this mode should not activate.
The trigger description uses general states like "scattered," "doing admin/errands," and "start-of-day organisation," which are common situations rather than specific invocation cues. The file does not provide constraints, explicit trigger phrases, or negative examples to clarify when this mode should or should not activate.
The phrase "When: spending intentional time with partner/family/friends" is a high-level life context rather than a specific invocation trigger. It lacks clear boundaries, examples, or exclusions, so it could overlap with common daily interactions and make it unclear when this mode should activate versus not activate.
The trigger list uses subjective, everyday states like "stuck" and broad emotional conditions such as "dysregulated" or "spiralling" without defining scope or exclusion conditions. Because the file provides no negative examples or contextual constraints, the skill could activate in situations far beyond the intended reset use case.
The phrase "end of workday OR late evening" is subjective and varies by user, schedule, and context. The file does not define concrete boundaries or exclusions, so the mode could be invoked unintentionally in common situations.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def sh(cmd: list[str]) -> str:
try:
return subprocess.check_output(cmd, text=True)
except subprocess.CalledProcessError as e:
# Preserve any partial output for debugging.
if e.output:
No suspicious patterns detected.