Skip to content

security(imessage): scope pairing-store auth to accountId#26688

Closed
bmendonca3 wants to merge 2 commits intoopenclaw:mainfrom
bmendonca3:bm/imessage-pairing-account-scope-20260225-r20
Closed

security(imessage): scope pairing-store auth to accountId#26688
bmendonca3 wants to merge 2 commits intoopenclaw:mainfrom
bmendonca3:bm/imessage-pairing-account-scope-20260225-r20

Conversation

@bmendonca3
Copy link
Copy Markdown
Contributor

@bmendonca3 bmendonca3 commented Feb 25, 2026

Summary

iMessage inbound DM pairing auth in monitor-provider used channel-level pairing-store reads/writes without accountId. In multi-account iMessage setups, approvals/pairing state from one account could influence DM authorization decisions in another account on the same gateway.

This PR scopes both pairing-store read and pairing-request upsert to the active iMessage account.

Change Type

  • Security fix (authz boundary hardening)
  • Tests

Scope

  • src/imessage/monitor/monitor-provider.ts
  • src/imessage/monitor/monitor-provider.account-scope.test.ts

Security Impact

  • Boundary crossed (before fix): per-account DM pairing auth consumed/wrote unscoped pairing-store state.
  • Practical impact: approved sender state from account A could affect account B DM gating.
  • Worst case: cross-account unauthorized DM command execution path in shared multi-account gateways.

Repro + Verification

Deterministic repro (local)

  1. Configure two iMessage accounts on one gateway (accountA, accountB) with dmPolicy: pairing.
  2. Trigger pairing from sender X on accountA and approve.
  3. Send DM from sender X to accountB.
  4. Before fix: unscoped pairing-store state can be reused across accounts.
  5. After fix: iMessage monitor reads/writes pairing-store state with accountId, preventing cross-account authorization leakage.

Automated verification

pnpm vitest run --config vitest.unit.config.ts --maxWorkers=1 \
  src/imessage/monitor/monitor-provider.account-scope.test.ts \
  src/imessage/monitor/provider.group-policy.test.ts

All pass.

Evidence

Human Verification

  • Confirmed monitor ingress now calls:
    • readChannelAllowFromStore("imessage", process.env, accountInfo.accountId)
    • upsertChannelPairingRequest({ ..., accountId: accountInfo.accountId })
  • Added focused regression test that drives monitor ingress and asserts account-scoped read/write call arguments.

Compatibility / Migration

  • No config migration required.
  • Single-account behavior is unchanged.

Failure Recovery

  • Revert this commit to restore prior behavior.
  • If needed operationally, temporarily set iMessage dmPolicy: open while account-specific pairing entries are re-established.

Risks and Mitigations

  • Risk: operators may need separate pairing approvals per account (intended boundary behavior).
  • Mitigation: targeted regression test now enforces account-scoped read/write behavior in monitor ingress.

Greptile Summary

Adds accountId parameter to readChannelAllowFromStore and upsertChannelPairingRequest calls in iMessage monitor to prevent cross-account authorization leakage in multi-account gateway setups. The pairing-store functions already support accountId scoping (lines 334-351 and 471-498 in pairing-store.ts), and this PR ensures the iMessage monitor uses that parameter correctly.

Confidence Score: 5/5

  • Safe to merge - this is a targeted security fix with focused test coverage
  • The changes correctly add accountId scoping to existing pairing-store functions that already support this parameter. The implementation is minimal (2 call sites updated), the test verifies the fix works as intended, and Telegram already uses this pattern correctly (line 398 in bot-handlers.ts). No logic errors or edge cases identified.
  • No files require special attention

Last reviewed commit: b414440

@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 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: imessage Channel integration: imessage size: S stale Marked as stale due to inactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants