T06 · System Persistence
- Location
scripts/schedule.py:162- Finding
User crontab is replaced instead of safely updating Skill-owned entries
- Content
View full analysis
Vulnerability Details
File Location:
scripts/schedule.py, lines 162–210
Vulnerability Type: Destructive scheduled-task persistence management
Risk Level: HighVulnerable Code
python def update_crontab(tasks): lines = [ "# OpenClaw scheduled tasks", "# Edit: crontab -e", "# View: crontab -l", "", "SHELL=/bin/bash", "PATH=/usr/local/bin:/usr/bin:/bin:/home/wang/.npm-global/bin", "", "# Daily scheduled tasks" ] for task in tasks: if task.get('status') == '✅': time_parts = task['time'].split(':') hour = time_parts[0] minute = time_parts[1] weekday = task.get('weekday', '1-7') if weekday == '1-5': day_of_week = "1-5" elif weekday == '1-7' or weekday == '*': day_of_week = "*" else: day_of_week = weekday lines.append(f"{minute} {hour} * * {day_of_week} {RUN_TASK_SCRIPT} \"{task['name']}\"") crontab_content = '\n'.join(lines) + '\n' try: proc = subprocess.Popen( ['crontab', '-'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) stdout, stderr = proc.communicate(crontab_content.encode())Technical Analysis
The
crontab -command installs its standard input as the complete crontab of the current operating-system user. The function constructs that input solely from tasks managed by this Skill. It does not read the existing crontab, preserve unrelated entries, or delimit Skill-owned records with managed-section markers.Consequently, every operation that calls
update_crontab()—including adding, editing, enabling, disabling, toggling, or deleting a task—replaces the user's entire crontab. Scheduling persistence is necessar ...[truncated 1266 chars]- Remediation
View remediation
Remediation Suggestions
- Read the existing crontab with
crontab -lbefore making changes. - Manage only a clearly delimited section, for example:
text # BEGIN OPENCLAW SCHEDULE-MANAGER ... # END OPENCLAW SCHEDULE-MANAGER - Replace only the content inside those markers and preserve every unrelated line byte-for-byte.
- Back up the original crontab before installation and restore it if installation fails.
- Show the proposed changes and require explicit user confirmation before the first cron modification.
- Provide an uninstall or cleanup command that removes only the managed section.
- Prefer a single fixed dispatcher entry rather than installing one cron record per user task.
- Never require elevated privileges; modify only the invoking user's crontab.
- Read the existing crontab with
