Medium severity5.3NVD Advisory· Published May 11, 2026· Updated May 13, 2026
CVE-2026-44999
CVE-2026-44999
Description
OpenClaw before 2026.4.20 fails to properly preserve untrusted labels for isolated cron awareness events, allowing webhook-triggered cron agent output to be recorded as trusted system events. Attackers can exploit this trust-labeling issue to strengthen prompt-injection attacks by rendering untrusted events as trusted System events.
Affected products
1Patches
1f61896b03cc7fix(cron): preserve untrusted awareness event labels (#68210)
6 files changed · +50 −2
CHANGELOG.md+1 −0 modified@@ -32,6 +32,7 @@ Docs: https://docs.openclaw.ai - Models status/OAuth health: align OAuth health reporting with the same effective credential view runtime uses, so expired refreshable sessions stop showing healthy by default and fresher imported Codex CLI credentials surface correctly in `models status`, doctor, and gateway auth status. Thanks @vincentkoc. - Twitch/setup: load Twitch through the bundled setup-entry discovery path and keep setup/status account detection aligned with runtime config. (#68008) Thanks @gumadeiras. - Feishu/card actions: resolve card-action chat type from the Feishu chat API when stored context is missing, preferring `chat_mode` over `chat_type`, so DM-originated card actions no longer bypass `dmPolicy` by falling through to the group handling path. (#68201) +- Cron/isolated-agent: preserve `trusted: false` on isolated cron awareness events mirrored into the main session, and forward the optional `trusted` flag through the gateway cron wrapper so explicit trust downgrades survive session-key scoping. (#68210) ## 2026.4.15
src/cron/isolated-agent/delivery-dispatch.double-announce.test.ts+1 −0 modified@@ -324,6 +324,7 @@ describe("dispatchCronDelivery — double-announce guard", () => { expect(enqueueSystemEvent).toHaveBeenCalledWith("Morning briefing complete.", { sessionKey: "agent:main:main", contextKey: "cron-direct-delivery:v1:run-123:telegram::123456:", + trusted: false, }); });
src/cron/isolated-agent/delivery-dispatch.ts+1 −0 modified@@ -351,6 +351,7 @@ async function queueCronAwarenessSystemEvent(params: { agentId: params.agentId, }), contextKey: params.deliveryIdempotencyKey, + trusted: false, }); } catch (err) { await logCronDeliveryWarn(
src/cron/service/state.ts+1 −1 modified@@ -62,7 +62,7 @@ export type CronServiceDeps = { maxMissedJobsPerRestart?: number; enqueueSystemEvent: ( text: string, - opts?: { agentId?: string; sessionKey?: string; contextKey?: string }, + opts?: { agentId?: string; sessionKey?: string; contextKey?: string; trusted?: boolean }, ) => void; requestHeartbeatNow: (opts?: { reason?: string; agentId?: string; sessionKey?: string }) => void; runHeartbeatOnce?: (opts?: {
src/gateway/server-cron.test.ts+41 −0 modified@@ -140,6 +140,47 @@ describe("buildGatewayCronService", () => { } }); + it("preserves trust downgrades when cron enqueues system events", () => { + const cfg = createCronConfig("server-cron-untrusted"); + loadConfigMock.mockReturnValue(cfg); + + const state = buildGatewayCronService({ + cfg, + deps: {} as CliDeps, + broadcast: () => {}, + }); + try { + const cronDeps = ( + state.cron as unknown as { + state?: { + deps?: { + enqueueSystemEvent?: (optsText: string, opts?: { + agentId?: string; + sessionKey?: string; + contextKey?: string; + trusted?: boolean; + }) => void; + }; + }; + } + ).state?.deps; + + cronDeps?.enqueueSystemEvent?.("hello", { + sessionKey: "discord:channel:ops", + contextKey: "cron:test", + trusted: false, + }); + + expect(enqueueSystemEventMock).toHaveBeenCalledWith("hello", { + sessionKey: "agent:main:discord:channel:ops", + contextKey: "cron:test", + trusted: false, + }); + } finally { + state.cron.stop(); + } + }); + it("blocks private webhook URLs via SSRF-guarded fetch", async () => { const cfg = createCronConfig("server-cron-ssrf"); loadConfigMock.mockReturnValue(cfg);
src/gateway/server-cron.ts+5 −1 modified@@ -285,7 +285,11 @@ export function buildGatewayCronService(params: { agentId, requestedSessionKey: opts?.sessionKey, }); - enqueueSystemEvent(text, { sessionKey, contextKey: opts?.contextKey }); + enqueueSystemEvent(text, { + sessionKey, + contextKey: opts?.contextKey, + trusted: opts?.trusted, + }); }, requestHeartbeatNow: (opts) => { const { agentId, sessionKey } = resolveCronWakeTarget(opts);
Vulnerability mechanics
AI mechanics synthesis has not run for this CVE yet.
References
3News mentions
0No linked articles in our index yet.