Medium severity4.2NVD Advisory· Published May 11, 2026· Updated May 13, 2026
CVE-2026-44991
CVE-2026-44991
Description
OpenClaw before 2026.4.21 contains an authorization bypass vulnerability in command-auth.ts that allows non-owner senders to execute owner-enforced slash commands when wildcard inbound senders are configured without explicit owner allowFrom settings. Attackers can exploit this by sending commands like /send, /config, or /debug on affected channels to bypass owner-only command authorization checks.
Affected products
1Patches
2995febb7b1e8fix: require owner identity for owner-enforced commands (#69774)
3 files changed · +47 −3
CHANGELOG.md+4 −0 modified@@ -14,6 +14,10 @@ Docs: https://docs.openclaw.ai - Image generation: log failed provider/model candidates at warn level before automatic provider fallback, so OpenAI image failures are visible in the gateway log even when a later provider succeeds. - npm/install: mirror the `node-domexception` alias into root `package.json` `overrides`, so npm installs stop surfacing the deprecated `google-auth-library -> gaxios -> node-fetch -> fetch-blob -> node-domexception` chain pulled through Pi/Google runtime deps. Thanks @vincentkoc. +### Fixes + +- Auth/commands: require owner identity (an owner-candidate match or internal `operator.admin`) for owner-enforced commands instead of treating wildcard channel `allowFrom` or empty owner-candidate lists as sufficient, so non-owner senders can no longer reach owner-only commands through a permissive fallback when `enforceOwnerForCommands=true` and `commands.ownerAllowFrom` is unset. (#69774) Thanks @drobison00. + ## 2026.4.20 ### Changes
src/auto-reply/command-auth.ts+1 −3 modified@@ -706,9 +706,7 @@ export function resolveCommandAuthorization(params: { ? true : ownerAllowlistConfigured ? senderIsOwner - : ownerState.allowAll || - ownerState.ownerCandidatesForCommands.length === 0 || - Boolean(matchedCommandOwner); + : senderIsOwnerByScope || Boolean(matchedCommandOwner); const isAuthorizedSender = resolveCommandSenderAuthorization({ commandAuthorized, isOwnerForCommands,
src/auto-reply/command-control.test.ts+42 −0 modified@@ -159,6 +159,48 @@ describe("resolveCommandAuthorization", () => { expect(otherAuth.isAuthorizedSender).toBe(false); }); + it("rejects wildcard channel senders when the plugin enforces owner-only commands", () => { + setActivePluginRegistry( + createTestRegistry([ + { + pluginId: "discord", + plugin: { + ...createOutboundTestPlugin({ + id: "discord", + outbound: { deliveryMode: "direct" }, + }), + commands: { enforceOwnerForCommands: true }, + config: { + listAccountIds: () => ["default"], + resolveAccount: () => ({}), + resolveAllowFrom: () => ["*"], + formatAllowFrom, + }, + }, + source: "test", + }, + ]), + ); + const cfg = { + channels: { discord: { allowFrom: ["*"] } }, + } as OpenClawConfig; + + const auth = resolveCommandAuthorization({ + ctx: { + Provider: "discord", + Surface: "discord", + ChatType: "direct", + From: "discord:123", + SenderId: "123", + } as MsgContext, + cfg, + commandAuthorized: true, + }); + + expect(auth.senderIsOwner).toBe(false); + expect(auth.isAuthorizedSender).toBe(false); + }); + it("uses explicit owner allowlist when allowFrom is empty", () => { const cfg = { commands: { ownerAllowFrom: ["whatsapp:+15551234567"] },
2aa93d44a1b2fix: require owner identity for owner-enforced commands (#69774)
3 files changed · +47 −3
CHANGELOG.md+4 −0 modified@@ -9,6 +9,10 @@ Docs: https://docs.openclaw.ai - Onboard/wizard: simplify the security disclaimer copy (drop the yellow banner and warning icon in favor of plain-prose paragraphs), and flip remaining onboarding pickers with long dynamic option lists to searchable autocompletes (search provider, plugin configure, model provider filter). - Ollama/onboard: populate the cloud-only model list from `ollama.com/api/tags` so `openclaw onboard` reflects the live cloud catalog instead of a static three-model seed; cap the discovered list at 500 and fall back to the previous hardcoded suggestions when ollama.com is unreachable or returns no models. (#68463) Thanks @BruceMacD. +### Fixes + +- Auth/commands: require owner identity (an owner-candidate match or internal `operator.admin`) for owner-enforced commands instead of treating wildcard channel `allowFrom` or empty owner-candidate lists as sufficient, so non-owner senders can no longer reach owner-only commands through a permissive fallback when `enforceOwnerForCommands=true` and `commands.ownerAllowFrom` is unset. (#69774) Thanks @drobison00. + ## 2026.4.20 ### Changes
src/auto-reply/command-auth.ts+1 −3 modified@@ -706,9 +706,7 @@ export function resolveCommandAuthorization(params: { ? true : ownerAllowlistConfigured ? senderIsOwner - : ownerState.allowAll || - ownerState.ownerCandidatesForCommands.length === 0 || - Boolean(matchedCommandOwner); + : senderIsOwnerByScope || Boolean(matchedCommandOwner); const isAuthorizedSender = resolveCommandSenderAuthorization({ commandAuthorized, isOwnerForCommands,
src/auto-reply/command-control.test.ts+42 −0 modified@@ -159,6 +159,48 @@ describe("resolveCommandAuthorization", () => { expect(otherAuth.isAuthorizedSender).toBe(false); }); + it("rejects wildcard channel senders when the plugin enforces owner-only commands", () => { + setActivePluginRegistry( + createTestRegistry([ + { + pluginId: "discord", + plugin: { + ...createOutboundTestPlugin({ + id: "discord", + outbound: { deliveryMode: "direct" }, + }), + commands: { enforceOwnerForCommands: true }, + config: { + listAccountIds: () => ["default"], + resolveAccount: () => ({}), + resolveAllowFrom: () => ["*"], + formatAllowFrom, + }, + }, + source: "test", + }, + ]), + ); + const cfg = { + channels: { discord: { allowFrom: ["*"] } }, + } as OpenClawConfig; + + const auth = resolveCommandAuthorization({ + ctx: { + Provider: "discord", + Surface: "discord", + ChatType: "direct", + From: "discord:123", + SenderId: "123", + } as MsgContext, + cfg, + commandAuthorized: true, + }); + + expect(auth.senderIsOwner).toBe(false); + expect(auth.isAuthorizedSender).toBe(false); + }); + it("uses explicit owner allowlist when allowFrom is empty", () => { const cfg = { commands: { ownerAllowFrom: ["whatsapp:+15551234567"] },
Vulnerability mechanics
AI mechanics synthesis has not run for this CVE yet.
References
4- github.com/openclaw/openclaw/commit/2aa93d44a1b2c7058c371f261fda2b5d4de4a882nvdPatch
- github.com/openclaw/openclaw/commit/995febb7b1e811ff6a1df5b18c22de94103f4c9fnvdPatch
- github.com/openclaw/openclaw/security/advisories/GHSA-c28g-vh7m-fm7vnvdThird Party Advisory
- www.vulncheck.com/advisories/openclaw-authorization-bypass-in-owner-enforced-commands-via-wildcard-channel-sendersnvdThird Party AdvisoryPatch
News mentions
0No linked articles in our index yet.