T06 · System Persistence
- Location
scripts/push-toggle.js:21- Finding
Recurring Scheduled Tasks Create Cross-Session Persistence
- Content
View full analysis
Vulnerability Details
File Location:
scripts/push-toggle.js:21-24
Vulnerability Type:T06: System Persistence
Risk Level: HighComplete Code Snippet
js const sk=`agent:main:${ch}:direct:${userId}`; console.log('__OPENCLAW_CRON_ADD__:'+JSON.stringify({name:`${SKILL}-morning-${userId}`,cronExpr:`${mm} ${mh} * * *`,tz:'Asia/Shanghai',session:'isolated',sessionKey:sk,channel:ch,to:userId,announce:true,timeoutSeconds:180,message:`node ${path.join(__dirname,'morning-push.js')} ${userId}`})); console.log('__OPENCLAW_CRON_ADD__:'+JSON.stringify({name:`${SKILL}-evening-${userId}`,cronExpr:`${em} ${eh} * * *`,tz:'Asia/Shanghai',session:'isolated',sessionKey:sk,channel:ch,to:userId,announce:true,timeoutSeconds:180,message:`node ${path.join(__dirname,'evening-push.js')} ${userId}`})); saveUser(userId,{...user,morningTime:mt,eveningTime:et,channel:ch,pushEnabled:true,updatedAt:new Date().toISOString()});The corresponding removal logic is located at
scripts/push-toggle.js:27-31:js function disablePush(userId){ userId=sanitizeId(userId); console.log(`__OPENCLAW_CRON_RM__:${SKILL}-morning-${userId}`); console.log(`__OPENCLAW_CRON_RM__:${SKILL}-evening-${userId}`); saveUser(userId,{...loadUser(userId),pushEnabled:false,updatedAt:new Date().toISOString()});Technical Analysis
When the documented
oncommand is invoked, the script emits two__OPENCLAW_CRON_ADD__control records. These records request daily morning and evening jobs that execute the bundled Node.js scripts and announce their output to a configured messaging recipient.The jobs continue beyond the lifetime of the process that creates them and remain active until explicitly removed. The script also stores persistent per-user configuration under
data/users, including the enabled state, delivery channel, and execution times.The feature is openly documented and its inputs are constrained: user IDs are allowlisted by pattern, times are validated, and chan ...[truncated 1443 chars]
- Remediation
View remediation
Remediation Suggestions
- Require explicit informed confirmation immediately before creating recurring jobs.
- Display the exact commands, delivery destination, schedule, time zone, and persistence duration before activation.
- Prefer schedules with an expiration date or a bounded opt-in period, requiring renewal for continued operation.
- Record stable scheduler job identifiers and verify ownership before updating or removing jobs.
- Provide automatic cleanup for expired, orphaned, or partially configured schedules.
- Ensure disabling the feature verifies that both jobs were actually removed rather than only emitting removal requests and updating local state.
- Clearly document where scheduler entries and per-user configuration are stored.
- Protect referenced scripts and their parent directory from unauthorized modification so an existing scheduled job cannot become an execution path for replaced code.
