Skip to content

fix(auth): treat unconfigured-owner sessions as owner for ownerOnly tools#26331

Merged
jalehman merged 3 commits intoopenclaw:mainfrom
widingmarcus-cyber:fix/cron-tool-schema-26319
Mar 6, 2026
Merged

fix(auth): treat unconfigured-owner sessions as owner for ownerOnly tools#26331
jalehman merged 3 commits intoopenclaw:mainfrom
widingmarcus-cyber:fix/cron-tool-schema-26319

Conversation

@widingmarcus-cyber
Copy link
Copy Markdown
Contributor

@widingmarcus-cyber widingmarcus-cyber commented Feb 25, 2026

Closes #26319
Also fixes #26665

Problem

When no commands.ownerAllowFrom is configured (the common single-user setup), senderIsOwner was always false. This happened because matchedSender requires a non-empty ownerList to match against, and without explicit owner configuration the list is empty.

As a result, ownerOnly tools (cron, gateway, whatsapp_login) were silently filtered from the agent's tool list by applyOwnerOnlyToolPolicy, even for the sole authorized user of the bot.

openclaw sandbox explain showed cron in the allow list (because it doesn't account for ownerOnly filtering), creating a confusing mismatch.

Root Cause

In command-auth.ts, the senderIsOwner flag was computed as:

const senderIsOwner = Boolean(matchedSender);

When ownerList is empty (no ownerAllowFrom configured), matchedSender is always undefined, so senderIsOwner is always false.

Fix

When no owner allowlist is configured, default senderIsOwner to true for any identified sender. This matches the expected single-user behavior: if you're authorized to talk to the bot and haven't configured multi-user ownership, you're the owner.

const senderIsOwner = ownerAllowAll
  || (!ownerAllowlistConfigured && Boolean(senderId))
  || Boolean(matchedSender);

When ownerAllowFrom IS configured, behavior is unchanged: only matched senders are owners.

Testing

  • 4 new tests covering: default (no config), non-matching, matching, and wildcard owner scenarios
  • All 24 existing command-control tests pass
  • All 3 whatsapp-login-gating tests pass (also tests senderIsOwner behavior)

Greptile Summary

Fixed senderIsOwner logic to default to true for single-user setups (no commands.ownerAllowFrom configured), ensuring ownerOnly tools (cron, gateway, whatsapp_login) are available to authorized users.

  • Modified src/auto-reply/command-auth.ts:349-350 to check if owner allowlist is unconfigured and sender is identified
  • Added comprehensive test coverage in src/auto-reply/command-auth.owner-default.test.ts covering default, non-matching, matching, and wildcard scenarios
  • Logic correctly handles edge cases: no senderId, wildcard, and explicit owner lists
  • Maintains backward compatibility for multi-user setups with explicit owner configuration

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The fix is well-targeted, logically sound, and thoroughly tested. The change addresses a clear bug where senderIsOwner was incorrectly false for single-user setups. The new logic correctly evaluates all scenarios: wildcard, explicit owner lists, and the default no-config case. Four comprehensive tests cover all branches. All existing tests pass (24 command-control + 3 whatsapp-login-gating tests). The implementation follows project conventions with clear comments explaining the rationale. No security concerns or edge cases identified.
  • No files require special attention

Last reviewed commit: b92f3e3

@widingmarcus-cyber
Copy link
Copy Markdown
Contributor Author

@greptile-apps please review

@widingmarcus-cyber widingmarcus-cyber force-pushed the fix/cron-tool-schema-26319 branch 2 times, most recently from 9268ad5 to 61e05b3 Compare February 25, 2026 15:51
@widingmarcus-cyber
Copy link
Copy Markdown
Contributor Author

@greptile-apps please review

@widingmarcus-cyber widingmarcus-cyber force-pushed the fix/cron-tool-schema-26319 branch from 61e05b3 to 20c7859 Compare February 26, 2026 10:25
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Feb 26, 2026

Greptile Summary

Fixed authentication logic to correctly treat users as owners in single-user setups (no commands.ownerAllowFrom configured). Previously, senderIsOwner was always false when no owner allowlist was configured, which silently hid ownerOnly tools (cron, gateway, whatsapp_login) even for the sole authorized user.

  • Modified senderIsOwner calculation in src/auto-reply/command-auth.ts:350 to default to true when no owner allowlist is configured and a valid senderId exists
  • Added comprehensive test coverage with 4 test cases covering default, non-matching, matching, and wildcard owner scenarios
  • When ownerAllowFrom IS configured, behavior remains unchanged (only matched senders are owners)
  • All existing tests pass (24 command-control tests, 3 whatsapp-login-gating tests)

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The fix is well-scoped, thoroughly tested, and addresses a clear bug without introducing security concerns. The logic correctly handles the default single-user case while preserving existing behavior for configured multi-user setups. The code includes helpful comments explaining the change, and all existing tests pass.
  • No files require special attention

Last reviewed commit: 20c7859

@openclaw-barnacle
Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle bot added the stale Marked as stale due to inactivity label Mar 4, 2026
@jalehman jalehman self-assigned this Mar 6, 2026
@jalehman jalehman force-pushed the fix/cron-tool-schema-26319 branch from 90300e5 to 420786d Compare March 6, 2026 23:10
@aisle-research-bot
Copy link
Copy Markdown

aisle-research-bot bot commented Mar 6, 2026

🔒 Aisle Security Analysis

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

# Severity Title
1 🔴 Critical Owner-only tool privilege escalation: any direct-chat sender treated as owner when owner allowlist unset

1. 🔴 Owner-only tool privilege escalation: any direct-chat sender treated as owner when owner allowlist unset

Property Value
Severity Critical
CWE CWE-269
Location src/auto-reply/command-auth.ts:353-361

Description

The new default-owner logic in resolveCommandAuthorization marks any identified direct-chat sender as an owner whenever no explicit owner allowlist is configured:

  • senderIsOwner becomes true when !ownerAllowlistConfigured && isDirectChat && Boolean(senderId)
  • senderId can be derived from ctx.SenderId or fallback candidates (including ctx.From in direct chats)
  • This owner flag is then used to permit owner-only tools (e.g., gateway, cron, whatsapp_login) via applyOwnerOnlyToolPolicy.

This enables privilege escalation in realistic deployments where direct messages are not single-user in the security sense:

  • Discord: with dmPolicy="open", any user can DM the bot; commandAuthorized becomes true for open DMs, and with this change the sender also becomes senderIsOwner, enabling owner-only tools.
  • Slack: with dmPolicy="open", any user can DM the bot; even if CommandAuthorized remains false, the owner-only tool filter uses only senderIsOwner, so owner-only tools can still be exposed to arbitrary DM senders.
  • Pairing flows / multi-user deployments: if multiple users become DM-authorized (via pairing store, wildcard allowFrom, etc.), every such DM sender becomes an “owner” under this default.

Vulnerable code (introduced behavior):

const senderIsOwner =
  senderIsOwnerByIdentity ||
  senderIsOwnerByScope ||
  ownerAllowAll ||
  (!ownerAllowlistConfigured && isDirectChat && Boolean(senderId));

Security impact:

  • Owner-only tools include gateway (restart, config.apply/config.patch, update.run) and cron (manage scheduled jobs), which are highly sensitive and can lead to full service compromise.

Recommendation

Do not infer owner privileges from ChatType="direct" alone.

Safer options:

  1. Require explicit owner allowlisting for owner-only tools (recommended default):
  • Revert to senderIsOwner = senderIsOwnerByIdentity || senderIsOwnerByScope || ownerAllowAll.
  • Keep direct-chat usability by documenting that deployments must set commands.ownerAllowFrom (or an equivalent explicit owner identity) to enable owner-only tools.
  1. If you need a “single-user DM default” mode, gate it behind an explicit config flag and a single-identity guarantee, e.g.:
  • Only enable if the DM access allowlist resolves to exactly one normalized identity (and no wildcard), and it matches the sender.
  • Additionally require commandAuthorized === true so unauthenticated DMs cannot become owners.

Example safer logic sketch:

const allowSingleUserDmOwner = cfg.commands?.assumeSingleUserDirectChatOwner === true;
const senderIsOwner =
  senderIsOwnerByIdentity ||
  senderIsOwnerByScope ||
  ownerAllowAll ||
  (allowSingleUserDmOwner && commandAuthorized && isDirectChat && senderMatchesSoleConfiguredDmOwner);

Also ensure the owner-only tool filtering uses senderIsOwner && isAuthorizedSender (or equivalent) when applicable, so unauthorized senders cannot access owner-only tools even if misclassified.


Analyzed PR: #26331 at commit 1fbe1c7

Last updated on: 2026-03-07T00:24:54Z

jalehman added 3 commits March 6, 2026 15:35
…ools (openclaw#26319)

When no commands.ownerAllowFrom is configured (single-user default),
senderIsOwner was always false because matchedSender requires a
non-empty ownerList. This caused ownerOnly tools (cron, gateway) to
be silently filtered from the agent's tool list even for the sole
authorized user.

Now senderIsOwner defaults to true when no owner allowlist is
configured, matching the expected single-user behavior.

# Conflicts:
#	src/auto-reply/command-auth.ts
@jalehman jalehman force-pushed the fix/cron-tool-schema-26319 branch from 420786d to 1fbe1c7 Compare March 6, 2026 23:36
@jalehman jalehman merged commit 48b3c4a into openclaw:main Mar 6, 2026
26 of 27 checks passed
@jalehman
Copy link
Copy Markdown
Contributor

jalehman commented Mar 6, 2026

Merged via squash.

Thanks @widingmarcus-cyber!

vincentkoc pushed a commit to BryanTegomoh/openclaw-fork that referenced this pull request Mar 8, 2026
…ools (openclaw#26331)

Merged via squash.

Prepared head SHA: 1fbe1c7
Co-authored-by: widingmarcus-cyber <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman
Saitop pushed a commit to NomiciAI/openclaw that referenced this pull request Mar 8, 2026
…ools (openclaw#26331)

Merged via squash.

Prepared head SHA: 1fbe1c7
Co-authored-by: widingmarcus-cyber <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman
jenawant pushed a commit to jenawant/openclaw that referenced this pull request Mar 10, 2026
…ools (openclaw#26331)

Merged via squash.

Prepared head SHA: 1fbe1c7
Co-authored-by: widingmarcus-cyber <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman
dhoman pushed a commit to dhoman/chrono-claw that referenced this pull request Mar 11, 2026
…ools (openclaw#26331)

Merged via squash.

Prepared head SHA: 1fbe1c7
Co-authored-by: widingmarcus-cyber <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman
senw-developers pushed a commit to senw-developers/va-openclaw that referenced this pull request Mar 17, 2026
…ools (openclaw#26331)

Merged via squash.

Prepared head SHA: 1fbe1c7
Co-authored-by: widingmarcus-cyber <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman
V-Gutierrez pushed a commit to V-Gutierrez/openclaw-vendor that referenced this pull request Mar 17, 2026
…ools (openclaw#26331)

Merged via squash.

Prepared head SHA: 1fbe1c7
Co-authored-by: widingmarcus-cyber <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 20, 2026
…ools (openclaw#26331)

Merged via squash.

Prepared head SHA: 1fbe1c7
Co-authored-by: widingmarcus-cyber <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

(cherry picked from commit 48b3c4a)
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 20, 2026
…ools (openclaw#26331)

Merged via squash.

Prepared head SHA: 1fbe1c7
Co-authored-by: widingmarcus-cyber <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

(cherry picked from commit 48b3c4a)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size: S stale Marked as stale due to inactivity

Projects

None yet

3 participants