Conversation
|
Codex review: needs maintainer review before merge. What this changes: The PR normalizes Voice Call and Google Meet webhook host checks for bracketed IPv6 and IPv4-mapped private or loopback URLs, adds regression coverage, and updates the changelog entry. Maintainer follow-up before merge: This is already an open implementation PR with a narrow, reviewable fix; the remaining action is maintainer review plus waiting for final required checks, not a separate automated repair branch. Security review: Security review cleared: The diff tightens webhook exposure classification and adds tests/changelog only; it does not change dependencies, workflows, permissions, scripts, package resolution, or secret handling. Review detailsBest possible solution: Land this PR or an equivalent narrow fix after CI: normalize webhook hostnames before local/private classification in both Voice Call and Google Meet setup, keep the regression tests, and consider a later shared-helper cleanup only if this duplicated logic starts drifting again. Do we have a high-confidence way to reproduce the issue? Yes. Current main can be reproduced with Node URL parsing for Is this the best way to solve the issue? Yes. The PR is the narrowest maintainable fix for the reported behavior: it corrects the classifier inputs and covers the CLI/runtime/Google Meet setup paths without changing provider contracts or adding dependencies. Acceptance criteria:
What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against ec1b96cdfa08. |
68f6b49 to
ccb06bb
Compare
|
Landed via squash after tightening the implementation to reuse the existing SSRF hostname/IP classifier.
Thanks @clawsweeper, @donkeykong91, and @PfanP. |
Summary
Found one concrete bug in the new webhook exposure checks: IPv6 loopback and unique-local webhook URLs are still treated as public/reachable, even though the commit and docs say local/private webhook URLs fail before joins.
What ClawSweeper Is Fixing
extensions/voice-call/src/webhook-exposure.ts:45isProviderUnreachableWebhookUrl()passesnew URL(webhookUrl).hostnameintoisLocalOnlyWebhookHost(). In Node, IPv6 URL hostnames are bracketed, for examplenew URL("http://[::1]:3334/voice/webhook").hostnamereturns"[::1]", not"::1". The helper compares against"::","::1", andhost.startsWith("fc") || host.startsWith("fd"), so bracketed"[::1]","[fc00::1]", and"[fd00::1]"all return false. The duplicate Google Meet helper has the same behavior atextensions/google-meet/src/setup.ts:50, andgetVoiceCallWebhookExposureCheck()then reportsok: truefor thosepublicUrlvalues atextensions/google-meet/src/setup.ts:65.voicecall setup,googlemeet setup --transport twilio, and the runtime fail-closed guard can approvepublicUrlvalues such ashttp://[::1]:3334/voice/webhookorhttp://[fd00::1]/voice/webhook. Twilio/Telnyx/Plivo callbacks will not be able to reach those URLs, so the user gets a green setup check and may start a join/call that cannot receive provider webhooks.node:net.isIPplus range checks, or an existing shared SSRF/private-IP helper). Add regression tests for::,::1,fc00::/7,fd00::/8, and IPv4-mapped loopback/private forms in both the shared voice-call helper and Google Meet setup path, or centralize the helper so they cannot drift.Expected Repair Surface
extensions/voice-call/src/webhook-exposure.tsextensions/google-meet/index.test.tsextensions/google-meet/src/setup.tsextensions/voice-call/index.test.tsextensions/voice-call/src/cli.tsextensions/voice-call/src/runtime.test.tsextensions/voice-call/src/runtime.tsSource And Review Context
ClawSweeper report: https://github.com/openclaw/clawsweeper/blob/main/records/openclaw-openclaw/commits/b2aac178d6da6ccd8228d4f8e20239153da4dcb9.md
Commit under review: b2aac17
Latest main at intake: 7340c03
Original commit author: Peter Steinberger
GitHub author: @steipete
Highest severity: medium
Review confidence: high
Diff:
464e57360262b7e0f9a705431bedd402fe8c356b..b2aac178d6da6ccd8228d4f8e20239153da4dcb9Changed files:
CHANGELOG.md,docs/plugins/google-meet.md,extensions/google-meet/index.test.ts,extensions/google-meet/src/setup.ts,extensions/voice-call/index.test.ts,extensions/voice-call/src/cli.ts,extensions/voice-call/src/runtime.test.ts,extensions/voice-call/src/runtime.ts,extensions/voice-call/src/webhook-exposure.tsCode read: Google Meet setup/runtime/tool path, voice-call CLI setup, runtime public webhook guard, new webhook exposure helper, adjacent config/provider contracts, changed tests, relevant Google Meet docs sections.
Dependencies/web: no dependency files changed; no web lookup needed.
Expected validation
pnpm check:changedClawSweeper already ran:
pnpm docs:listpnpm installafter the first test run showed missingvitest/package.jsonpnpm test extensions/voice-call/src/runtime.test.ts extensions/voice-call/index.test.ts extensions/google-meet/index.test.tspassed: 3 files, 94 tests.pnpm exec tsx ...extensions/voice-call/src/webhook-exposure.ts...reproduced the IPv6 false-negative.Known review limits:
ClawSweeper Guardrails
mainbefore changing code.ClawSweeper 🐠 replacement reef notes:
fish notes: model gpt-5.5, reasoning medium; reviewed against 68f6b49.