Skip to content

fix: block channel reads outside allowlists [AI]#98972

Open
pgondhi987 wants to merge 38 commits into
openclaw:mainfrom
pgondhi987:fix/fix-808
Open

fix: block channel reads outside allowlists [AI]#98972
pgondhi987 wants to merge 38 commits into
openclaw:mainfrom
pgondhi987:fix/fix-808

Conversation

@pgondhi987

@pgondhi987 pgondhi987 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Fixes an issue where users who restrict channel integrations to allowlisted group targets could still have agent-callable read actions query non-allowlisted Microsoft Teams, Feishu, Matrix, and Google Chat targets when the connected bot account could read them.

Why This Change Was Made

This adds channel-owned read-target authorization immediately before read-only provider API calls in the affected integrations. The checks reuse each plugin's existing route/group allowlist semantics and preserve current-conversation fallback behavior when the tool call does not provide its own target and the channel can prove the target before the read.

User Impact

Operators can expect group allowlists to apply consistently to message, reaction, pin, and metadata reads in the affected channel plugins. Out-of-allowlist reads now fail before the provider API call; auth, provider selection, config shape, storage, migrations, and write-action behavior are unchanged.

Compatibility note: Feishu messageId-only read/reaction paths now fail closed under allowlist or disabled-group verification, including trusted current-chat context, because an unscoped Feishu message ID cannot prove the message's actual chat before getMessageFeishu would be called. This intentionally prevents the provider-read-before-authorization path ClawSweeper flagged. Feishu chat-scoped reads such as pins, chat info, and member reads still use the existing allowed chat target checks; open-policy Feishu reads without disabled group entries are unchanged.

AI-assisted.

Evidence

  • Current head: 98a0e2b171ade1e67eba690311b6077054057e9b.
  • node scripts/run-vitest.mjs extensions/googlechat/src/actions.test.ts extensions/matrix/src/tool-actions.test.ts extensions/msteams/src/channel.actions.test.ts extensions/feishu/src/channel.test.ts passed 4 current-head Vitest shards: Feishu 96, Matrix 32, Microsoft Teams 50, Google Chat 8.
  • node scripts/run-tsgo.mjs -p tsconfig.extensions.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/extensions.tsbuildinfo passed.
  • git diff --check passed.
  • Regression tests assert out-of-allowlist read targets throw before the mocked provider runtime is called, while allowed/current-context controls still read through the intended channel adapter.
  • Feishu open-policy compatibility coverage now includes explicit chat: group read and reaction-read targets under groupPolicy: "open" with default DM policy.
  • Live provider credentials were not available in this environment; current proof is local adapter-boundary proof plus PR CI, with an explicit maintainer proof override posted on the PR.

@openclaw-barnacle openclaw-barnacle Bot added channel: googlechat Channel integration: googlechat channel: matrix Channel integration: matrix channel: msteams Channel integration: msteams channel: feishu Channel integration: feishu size: M maintainer Maintainer-authored PR labels Jul 2, 2026
@clawsweeper

clawsweeper Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Codex review: stale review; fresh review needed.

Summary
The latest durable ClawSweeper review was for head acf405c5832d220c51bf93544b1626467db24232, but the PR head is now 98a0e2b171ade1e67eba690311b6077054057e9b. Its old verdict and PR readiness labels are no longer current.

Next step
Run or wait for a fresh ClawSweeper review on the current PR head.

Review history (1 earlier review cycle)
  • reviewed 2026-07-02T13:31:04.366Z sha acf405c :: needs maintainer review before merge. :: none

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels Jul 2, 2026
@pgondhi987

Copy link
Copy Markdown
Contributor Author

@clawsweeper address review.

@clawsweeper

clawsweeper Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🦞🔧
ClawSweeper did not dispatch a repair worker for this one.

Reason: repair commands require a ClawSweeper PR or a PR opted into ClawSweeper autofix or automerge.

Supported re-review commands work on open issues and PRs: /review, /clawsweeper re-review, or @clawsweeper re-review.
Supported issue implementation commands work on open issues: /clawsweeper implement, @clawsweeper fix, /clawsweeper build, @clawsweeper create pr, or @clawsweeper fix issue.
Supported repair commands work on existing ClawSweeper PRs and PRs opted into clawsweeper:autofix or clawsweeper:automerge: /clawsweeper fix ci, /clawsweeper address review, /clawsweeper rebase.
A maintainer can opt a PR in with /clawsweeper autofix or /clawsweeper automerge and I can take another pass.
A maintainer can close unsupported or declined work with /autoclose <reason>.

@pgondhi987

Copy link
Copy Markdown
Contributor Author

ClawSweeper proof for current head 62195fd

Behavior proved: agent-callable read actions in Microsoft Teams, Feishu, Matrix, and Google Chat enforce the OpenClaw channel allowlist before provider/native read sinks are reached.

Actual OpenClaw entry points exercised: MSTeams handleAction, Feishu channel handleAction, Matrix handleMatrixAction, and Google Chat action handling from the changed plugin modules.

Environment: local PR checkout on Node v24.15.0 plus GitHub Actions for PR #98972. Mantis status-only reported no current-head Telegram proof; no Mantis proof was requested because this GHSA is not a Telegram/visual-channel path and the proof below exercises the affected production channel action adapters.

Protected boundary and sinks: explicit to / target / chatId / roomId / Google Chat spaces/{space}/messages/{id} read targets must be authorized before calls such as getMessageMSTeams, Teams metadata/reaction/search reads, Feishu pin/member/reaction reads, Matrix reaction/message/member/room reads, and Google Chat reaction reads.

Command/artifact:

  • git diff --check
  • node scripts/run-vitest.mjs extensions/googlechat/src/actions.test.ts extensions/matrix/src/tool-actions.test.ts extensions/msteams/src/channel.actions.test.ts extensions/feishu/src/channel.test.ts
  • pnpm build
  • GitHub Actions CI run for head 62195fd0ee7bd4dac837d8d93643fd6c14718be5: https://github.com/openclaw/openclaw/actions/runs/28585544376

Evidence:

  • fixed/denied: focused Vitest output on the current head passed 4 shards: Feishu 71 tests, Matrix 22 tests, MSTeams 38 tests, Google Chat 8 tests. Denial tests include blocks explicit read targets outside the Teams route allowlist, blocks explicit read targets when Teams uses env-only credentials, blocks explicit read targets outside configured Teams routes under open sender policy, blocks message reads outside the Feishu group allowlist, blocks Feishu reaction reads when the target message is outside the group allowlist, blocks reaction reads outside the Matrix room allowlist, blocks room metadata reads outside the Matrix room allowlist, and blocks reaction reads outside the Google Chat space allowlist.
  • protected sink/source result: 0 provider/native read calls for denied out-of-allowlist targets. The denied tests assert the authorization error and not.toHaveBeenCalled() / equivalent zero-call count for the corresponding protected sinks, including Teams read/metadata/reaction/search mocks, Feishu read/pin/member/reaction mocks, Matrix read/reaction/member/room mocks, and Google Chat reaction read mocks. Sensitive out-of-allowlist message/reaction/member/channel output is therefore suppressed before the provider boundary.
  • control: allowed/benign controls passed in the same command, including allows explicit read targets inside the Teams route allowlist, allows explicit read targets inside configured Teams routes under open sender policy, allows reaction adds without read allowlist room matches, allows unmatched Matrix room reads under open policy when another room is configured, plus existing Feishu and Google Chat allowed-target controls. These prove intended allowed reads/writes still work.
  • local build: pnpm build completed successfully; slowest phase tsdown finished in 137.0s and ui:build finished in 2.41s.
  • CI: PR statusCheckRollup for the same head had no failing checks; CI, build-artifacts, check-prod-types, check-lint, check-test-types, QA Smoke CI, CodeQL, Opengrep, and guard workflows completed success/neutral/skipped as expected.

Compatibility/operator note: no action names, parameter shapes, response shapes, config keys, or migrations changed. The intended behavior change is that out-of-allowlist read targets now fail closed before provider reads.

Live gaps: no live Microsoft Teams, Feishu, Matrix, or Google Chat workspace credentials were used. The proof uses the closest production adapters in local runtime tests and stubs only the external provider/native read boundary to prove denied targets produce zero protected calls.

@pgondhi987

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@pgondhi987

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@pgondhi987

Copy link
Copy Markdown
Contributor Author

ClawSweeper proof for current head 239b29b

Behavior proved: agent-callable read and reaction-read actions in Microsoft Teams, Feishu, Matrix, and Google Chat enforce channel allowlist or disabled-target policy before protected provider/native read sinks are reached; allowed current-context and open-policy group controls continue to work.

Environment: local PR checkout at current head plus GitHub Actions PR CI. Authenticated GitHub user for this comment is pgondhi987; this PR is authored by pgondhi987 and has the protected maintainer label.

Maintainer proof override: no redacted live Teams, Feishu, Matrix, or Google Chat workspace credentials are available in this environment. As maintainer-owned PR evidence, I accept the current-head local adapter-boundary proof plus PR CI in lieu of live affected-provider proof for this PR, because the changed security boundary is the in-process channel authorization branch immediately before the provider/native read sink. The tests exercise the real channel action entry points and mock only the external provider boundary so they can assert zero protected calls for denied targets.

Protected boundary and sinks: explicit to / target / chatId / roomId / Google Chat spaces/{space}/messages/{id} read targets must be authorized before calls such as Teams message/metadata/reaction/search reads, Feishu getMessageFeishu and reaction/member/pin reads, Matrix message/reaction/member/room reads, and Google Chat reaction reads.

Command/artifact:

  • node scripts/run-vitest.mjs extensions/googlechat/src/actions.test.ts extensions/matrix/src/tool-actions.test.ts extensions/msteams/src/channel.actions.test.ts extensions/feishu/src/channel.test.ts
  • node scripts/run-tsgo.mjs -p tsconfig.extensions.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/extensions.tsbuildinfo
  • git diff --check
  • GitHub Actions current-head checks include Real behavior proof success at https://github.com/openclaw/openclaw/actions/runs/28605898480/job/84825915567 and CI run https://github.com/openclaw/openclaw/actions/runs/28605904018

Evidence:

  • fixed/denied: current-head focused Vitest passed 4 shards: Feishu 94 tests, Matrix 32 tests, Microsoft Teams 50 tests, Google Chat 8 tests. Denial cases assert the authorization error and zero provider/native read calls for out-of-allowlist read targets.
  • protected sink/source result: denied Feishu messageId-only, explicit direct, p2p chat-id, disallowed group, reaction-read, reaction-removal, and clear-all reaction paths do not call getMessageFeishu; denied sibling channel paths likewise assert zero mocked provider/native read calls.
  • control: allowed/current-context controls pass in the same run, including allowed Teams route reads, Matrix paired-DM/current room reads, Google Chat allowed space reactions, trusted Feishu current-context reads/reactions, and explicit Feishu chat: group read/reaction targets under groupPolicy: "open" with default DM policy.

Compatibility/operator note: ambiguous or unscoped Feishu messageId read/reaction paths now fail closed when the target cannot be authorized before getMessageFeishu; prefixed open-policy Feishu group targets remain compatible and are verified after fetch. Auth, provider selection, config shape, storage, migrations, and write-action behavior are unchanged.

Live gaps: no live Teams, Feishu, Matrix, or Google Chat provider workspace was available from this environment, and Mantis Telegram proof is not applicable to these affected providers. The proof override above is the explicit maintainer acceptance for using current-head local adapter-boundary proof and CI instead of live affected-provider proof.

@pgondhi987

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@pgondhi987 pgondhi987 added the proof: override Maintainer override for the external PR real behavior proof gate. label Jul 2, 2026
@pgondhi987

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper clawsweeper Bot added status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 2, 2026
@pgondhi987

Copy link
Copy Markdown
Contributor Author

ClawSweeper proof for current head 98a0e2b

Behavior proved: agent-callable read and reaction-read actions in Microsoft Teams, Feishu, Matrix, and Google Chat enforce channel allowlist or disabled-target policy before protected provider/native read sinks are reached; allowed current-context and open-policy group controls continue to work.

Environment: local PR checkout at current head plus GitHub Actions PR CI. Authenticated GitHub user for this comment is pgondhi987; this PR is authored by pgondhi987 and has the protected maintainer label.

Maintainer proof override: no redacted live Teams, Feishu, Matrix, or Google Chat workspace credentials are available in this environment. As maintainer-owned PR evidence, I accept the current-head local adapter-boundary proof plus PR CI in lieu of live affected-provider proof for this PR, because the changed security boundary is the in-process channel authorization branch immediately before the provider/native read sink. The tests exercise the real channel action entry points and mock only the external provider boundary so they can assert zero protected calls for denied targets.

Protected boundary and sinks: explicit to / target / chatId / roomId / Google Chat spaces/{space}/messages/{id} read targets must be authorized before calls such as Teams message/metadata/reaction/search reads, Feishu getMessageFeishu and reaction/member/pin reads, Matrix message/reaction/member/room reads, and Google Chat reaction reads.

Command/artifact:

  • node scripts/run-vitest.mjs extensions/googlechat/src/actions.test.ts extensions/matrix/src/tool-actions.test.ts extensions/msteams/src/channel.actions.test.ts extensions/feishu/src/channel.test.ts
  • node scripts/run-tsgo.mjs -p tsconfig.extensions.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/extensions.tsbuildinfo
  • git diff --check
  • GitHub Actions current-head checks include Real behavior proof success at https://github.com/openclaw/openclaw/actions/runs/28607313625/job/84830758989 and CI run https://github.com/openclaw/openclaw/actions/runs/28607318044

Evidence:

  • fixed/denied: current-head focused Vitest passed 4 shards: Feishu 96 tests, Matrix 32 tests, Microsoft Teams 50 tests, Google Chat 8 tests. Denial cases assert the authorization error and zero provider/native read calls for out-of-allowlist read targets.
  • protected sink/source result: denied Feishu messageId-only, explicit direct, p2p chat-id, disallowed group, reaction-read, reaction-removal, clear-all reaction, and individual member-info paths do not call getMessageFeishu or getFeishuMemberInfo; denied sibling channel paths likewise assert zero mocked provider/native read calls.
  • control: allowed/current-context controls pass in the same run, including allowed Teams route reads, Matrix paired-DM/current room reads, Google Chat allowed space reactions, trusted Feishu current-context reads/reactions, and explicit Feishu chat: group read/reaction targets under groupPolicy: "open" with default DM policy.

Compatibility/operator note: ambiguous or unscoped Feishu messageId read/reaction paths now fail closed when the target cannot be authorized before getMessageFeishu; prefixed open-policy Feishu group targets remain compatible and are verified after fetch. Auth, provider selection, config shape, storage, migrations, and write-action behavior are unchanged.

Live gaps: no live Teams, Feishu, Matrix, or Google Chat provider workspace was available from this environment, and Mantis Telegram proof is not applicable to these affected providers. The proof override above is the explicit maintainer acceptance for using current-head local adapter-boundary proof and CI instead of live affected-provider proof.

@pgondhi987

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 2, 2026
@pgondhi987

Copy link
Copy Markdown
Contributor Author

currentDirectUserId is needed only for Matrix DM read authorization.

Why it exists:

  • Matrix current context has currentChannelId as the room, e.g. room:!
    dm:example.

  • For DM policy checks, room ID alone is not enough. The code needs to
    know the remote Matrix user, e.g. @alice:example.org, to evaluate
    dm.allowFrom.

  • Matrix builds that value from trusted inbound channel context in /home/
    ubuntu/Worktrees/openclaw/openclaw/fix/fix-808/extensions/matrix/src/
    channel.ts:665, using From, To, and ChatType.

  • The action layer then uses it in /home/ubuntu/Worktrees/openclaw/
    openclaw/fix/fix-808/extensions/matrix/src/tool-actions.ts:152 to allow
    current-DM reads only when:

    • requested room equals current room,
    • currentDirectUserId exists,
    • provider state verifies that room is actually bound to that user,
    • DM policy allows that user.

@joshavant joshavant self-assigned this Jul 3, 2026
@clawsweeper clawsweeper Bot removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. labels Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: web-ui App: web-ui channel: feishu Channel integration: feishu channel: googlechat Channel integration: googlechat channel: matrix Channel integration: matrix channel: msteams Channel integration: msteams gateway Gateway runtime maintainer Maintainer-authored PR P1 High-priority user-facing bug, regression, or broken workflow. proof: override Maintainer override for the external PR real behavior proof gate. size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants