fix(google-meet): validate chrome node policy params#103752
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 10, 2026, 9:26 PM ET / July 11, 2026, 01:26 UTC. Summary PR surface: Source +33, Tests +42. Total +75 across 2 files. Reproducibility: yes. Current main forwards incomplete bridge-control parameter objects to node-host handlers that require those fields, providing a high-confidence source reproduction without a live meeting. Review metrics: none identified. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the plugin-owned validation and canonical URL normalization after the branch and exact-head required checks satisfy the repository’s normal merge gates. Do we have a high-confidence way to reproduce the issue? Yes. Current main forwards incomplete bridge-control parameter objects to node-host handlers that require those fields, providing a high-confidence source reproduction without a live meeting. Is this the best way to solve the issue? Yes. Validating caller-controlled fields in the dangerous plugin invoke policy is the narrowest maintainable fix, and the proposed checks match both node-host requirements and established internal callers. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 790cd2aff2d4. Label changesLabel justifications:
Evidence reviewedPR surface: Source +33, Tests +42. Total +75 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (3 earlier review cycles) |
|
@clawsweeper re-review Added controlled runtime proof to the PR body and refreshed the branch onto current main. The proof loads the real Google Meet node invoke policy and dispatches approved calls into the real |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Merged via squash.
|
What Problem This Solves
Fixes an issue where caller-controlled
googlemeet.chromenode requests could forward malformed bridge-control parameters to the node host, so invalid audio bridge or stop-by-url requests failed after dispatch instead of being rejected at the plugin policy boundary.Why This Change Was Made
The dangerous Google Meet node command policy now validates the required fields for bridge-control actions before invoking the node host, and applies the same Meet URL normalization used by start/join flows to forwarded
listandstopByUrlfilters. Optional diagnostic actions such asstatusandstopkeep their existing behavior.User Impact
Google Meet chrome-node requests now get stable policy-denied errors for malformed bridge control and non-Meet URL filters before any node-side dispatch. Valid Meet URL filters keep query strings and still reach the node host in normalized form.
Evidence
OPENCLAW_HEAVY_CHECK_LOCK_SCOPE=worktree node scripts/run-vitest.mjs extensions/google-meet/src/node-invoke-policy.test.ts -- --reporter=verbosepnpm format:check extensions/google-meet/src/node-invoke-policy.ts extensions/google-meet/src/node-invoke-policy.test.tsOPENCLAW_HEAVY_CHECK_LOCK_SCOPE=worktree node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.extensions.json extensions/google-meet/src/node-invoke-policy.ts extensions/google-meet/src/node-invoke-policy.test.tsgit diff --check upstream/main..HEADnode --import tsx - <<'EOF' ...loaded the real Google Meet node invoke policy and dispatched approved calls into the realhandleGoogleMeetNodeHostCommandhandler.Proof
pullAudio,pushAudio,clearAudio, andstopByUrlrequests are denied beforeinvokeNodeis called.stopByUrlMeet URL filters are normalized and stripped of unrelated caller-controlled command fields before dispatch.GOOGLE_MEET_NODE_POLICY_DENIEDwithdispatched: 0; validstopByUrlandlistMeet URL filters reached the real node-host handler and returned stable JSON.stopByUrl.url:dispatched=0, denied before node-host dispatchstopByUrl.url:dispatched=0, denied before node-host dispatchpushAudio.base64:dispatched=0, denied before node-host dispatchstopByUrlMeet URL filter:dispatched=1, node-host returned{ ok: true, stopped: 0 }listMeet URL filter:dispatched=1, node-host returned{ bridges: [] }2upstream/main; final functional diff only touchesextensions/google-meet/src/node-invoke-policy.tsandextensions/google-meet/src/node-invoke-policy.test.ts.