Skip to content

fix(cron): preserve isolated message targets#69153

Merged
obviyus merged 9 commits into
openclaw:mainfrom
obviyus:fix/cron-isolated-telegram-targeting
Apr 20, 2026
Merged

fix(cron): preserve isolated message targets#69153
obviyus merged 9 commits into
openclaw:mainfrom
obviyus:fix/cron-isolated-telegram-targeting

Conversation

@obviyus

@obviyus obviyus commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Preserves explicit target context for isolated cron runs with delivery.mode: none, and forwards that context into embedded agent messaging.

@openclaw-barnacle openclaw-barnacle Bot added size: S maintainer Maintainer-authored PR labels Apr 20, 2026
@obviyus obviyus self-assigned this Apr 20, 2026
@greptile-apps

greptile-apps Bot commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a bug where explicit message targets in delivery.mode: none cron jobs were being discarded, and also fixes delivery-plan.ts so that channel only defaults to "last" for announce mode (not none). The hasMessageTargetContext guard in run.ts now correctly gates resolveDeliveryTarget on the presence of explicit to, threadId, or accountId fields — addressing the concern raised in the previous review thread.

Confidence Score: 5/5

Safe to merge — all prior P1 concerns are resolved, logic is correct, and new tests cover both the explicit-target forwarding and the bare-none early-exit path.

The previous thread's core concern (channel defaulting to 'last' making hasMessageTargetContext always true) is addressed by scoping the 'last' default only to announce mode in delivery-plan.ts. The hasMessageTargetContext guard correctly uses to/threadId/accountId rather than channel. Tests are thorough.

No files require special attention.

Reviews (2): Last reviewed commit: "test(cron): fix isolated target test typ..." | Re-trigger Greptile

Comment thread src/cron/isolated-agent/run.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4bd5fe7b9a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/cron/delivery-plan.ts
@obviyus

obviyus commented Apr 20, 2026

Copy link
Copy Markdown
Contributor Author

@greptile-apps review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c7bd3290a6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/cron/isolated-agent/run-executor.ts Outdated
@obviyus
obviyus force-pushed the fix/cron-isolated-telegram-targeting branch from c7bd329 to bf6ca5e Compare April 20, 2026 02:28
@aisle-research-bot

aisle-research-bot Bot commented Apr 20, 2026

Copy link
Copy Markdown

🔒 Aisle Security Analysis

We found 1 potential security issue(s) in this PR:

# Severity Title
1 🟠 High Cron isolated runs allow messaging target context even when delivery is not requested (mode:none)
1. 🟠 Cron isolated runs allow messaging target context even when delivery is not requested (mode:none)
Property Value
Severity High
CWE CWE-284
Location src/cron/isolated-agent/run.ts:144-178

Description

resolveCronDeliveryContext now resolves and forwards delivery target context to embedded agent runs even when cron delivery is not requested (deliveryPlan.requested === false) as long as any of to, threadId, or accountId is present (and mode is not webhook).

This can enable a control/authorization bypass depending on who can create/modify cron jobs:

  • For delivery.mode: "none", the embedded run still has the message tool enabled (disableMessageTool: false).
  • With this change, a job author can supply explicit delivery fields (e.g. to, threadId) and have them propagated into the embedded run as messageTo, messageThreadId, and derived currentChannelId.
  • Because requireExplicitMessageTarget is only enforced when deliveryRequested is true, the agent run may be able to send messages using these pre-filled defaults without an explicit user-provided target in the prompt.
  • Additionally, allowing accountId or threadId alone to trigger resolution can cause implicit last-target resolution via session state (channel: "last" with to: undefined), reintroducing implicit routing even when delivery is not requested.

Vulnerable logic (changed behavior):

const hasMessageTargetContext =
  deliveryPlan.mode !== "webhook" &&
  (deliveryPlan.to !== undefined ||
    deliveryPlan.threadId !== undefined ||
    deliveryPlan.accountId !== undefined);
if (!deliveryPlan.requested && !hasMessageTargetContext) {// ... skip resolution
}// otherwise resolves delivery target even when requested=false

If cron definitions are tenant-controlled or editable by less-trusted actors, this enables arbitrary outbound messaging/spam/exfiltration from cron runs by embedding a target in the job definition (or by causing implicit “last target” resolution via session state).

Recommendation

Tighten the conditions under which delivery target context is resolved/forwarded when delivery.mode is none.

Options (pick one based on intended product behavior):

  1. Strict: never resolve/forward any delivery target context unless deliveryPlan.requested === true.

  2. Explicit-only: if you want to allow message-tool defaults when mode:none, require that the target is fully explicit (e.g. to is set), and do not allow accountId or threadId alone to trigger resolution (which can fall back to implicit session targets):

const hasExplicitMessageTarget =
  deliveryPlan.mode === "none" && typeof deliveryPlan.to === "string" && deliveryPlan.to.trim();

if (!deliveryPlan.requested && !hasExplicitMessageTarget) {// do not resolve delivery target
}

Additionally, consider enforcing requireExplicitMessageTarget for mode:none when an explicit target is present, to avoid silent/default routing:

requireExplicitMessageTarget: params.resolvedDelivery.ok && (params.deliveryRequested || params.deliveryMode === "none")

Finally, ensure resolveDeliveryTarget (or the message tool) performs authorization/ACL checks for explicit targets in multi-tenant environments (e.g., verify the actor/cron owner can send to the requested to/channel/accountId).


Analyzed PR: #69153 at commit 05a1627

Last updated on: 2026-04-20T02:40:05Z

@obviyus
obviyus merged commit 7d9a9d8 into openclaw:main Apr 20, 2026
44 of 47 checks passed
@obviyus

obviyus commented Apr 20, 2026

Copy link
Copy Markdown
Contributor Author

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 05a16277f8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +147 to +149
(deliveryPlan.to !== undefined ||
deliveryPlan.threadId !== undefined ||
deliveryPlan.accountId !== undefined);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid resolving target for mode=none without explicit recipient

This condition treats threadId or accountId alone as “message target context”, which skips the early return and then calls resolveDeliveryTarget with channel: "last" later in the function; as a result, jobs like delivery: { mode: "none", accountId: "ops" } (or only threadId) can still inherit a session/default recipient and set currentChannelId, allowing agent message calls with no explicit target to go to a stale/default destination. That reintroduces implicit routing for a mode:none configuration that did not provide an explicit recipient.

Useful? React with 👍 / 👎.

lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
* test(cron): cover delivery target context for mode none

* fix(cron): preserve target context for delivery mode none

* test(cron): cover isolated message target forwarding

* fix(cron): forward isolated message targets into embedded runs

* fix(cron): ignore implicit last-target context for mode none

* fix(cron): keep mode none channel explicit only

* test(cron): fix isolated target test typing

* fix: preserve isolated message targets (openclaw#69153)

* fix: preserve isolated message targets (openclaw#69153)
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
* test(cron): cover delivery target context for mode none

* fix(cron): preserve target context for delivery mode none

* test(cron): cover isolated message target forwarding

* fix(cron): forward isolated message targets into embedded runs

* fix(cron): ignore implicit last-target context for mode none

* fix(cron): keep mode none channel explicit only

* test(cron): fix isolated target test typing

* fix: preserve isolated message targets (openclaw#69153)

* fix: preserve isolated message targets (openclaw#69153)
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
* test(cron): cover delivery target context for mode none

* fix(cron): preserve target context for delivery mode none

* test(cron): cover isolated message target forwarding

* fix(cron): forward isolated message targets into embedded runs

* fix(cron): ignore implicit last-target context for mode none

* fix(cron): keep mode none channel explicit only

* test(cron): fix isolated target test typing

* fix: preserve isolated message targets (openclaw#69153)

* fix: preserve isolated message targets (openclaw#69153)
globalcaos pushed a commit to globalcaos/tinkerclaw that referenced this pull request May 13, 2026
* test(cron): cover delivery target context for mode none

* fix(cron): preserve target context for delivery mode none

* test(cron): cover isolated message target forwarding

* fix(cron): forward isolated message targets into embedded runs

* fix(cron): ignore implicit last-target context for mode none

* fix(cron): keep mode none channel explicit only

* test(cron): fix isolated target test typing

* fix: preserve isolated message targets (openclaw#69153)

* fix: preserve isolated message targets (openclaw#69153)
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
* test(cron): cover delivery target context for mode none

* fix(cron): preserve target context for delivery mode none

* test(cron): cover isolated message target forwarding

* fix(cron): forward isolated message targets into embedded runs

* fix(cron): ignore implicit last-target context for mode none

* fix(cron): keep mode none channel explicit only

* test(cron): fix isolated target test typing

* fix: preserve isolated message targets (openclaw#69153)

* fix: preserve isolated message targets (openclaw#69153)
jameslcowan pushed a commit to jameslcowan/openclaw that referenced this pull request Jun 2, 2026
* test(cron): cover delivery target context for mode none

* fix(cron): preserve target context for delivery mode none

* test(cron): cover isolated message target forwarding

* fix(cron): forward isolated message targets into embedded runs

* fix(cron): ignore implicit last-target context for mode none

* fix(cron): keep mode none channel explicit only

* test(cron): fix isolated target test typing

* fix: preserve isolated message targets (openclaw#69153)

* fix: preserve isolated message targets (openclaw#69153)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer Maintainer-authored PR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant