From 0a53a77dd6f29bf8c65ec030b6282d45b013da4f Mon Sep 17 00:00:00 2001 From: Kriz Poon Date: Fri, 20 Feb 2026 15:31:17 +0000 Subject: [PATCH] Chrome extension: validate relay endpoint response format Options page now validates that /json/version returns valid CDP JSON (with Browser/Protocol-Version fields) rather than accepting any HTTP 200 response. This prevents false success when users mistakenly configure the gateway port instead of the relay port (gateway + 3). Helpful error messages now guide users to use "gateway port + 3" when they configure the wrong port. --- assets/chrome-extension/background.js | 13 +++++++++- assets/chrome-extension/options.js | 37 +++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/assets/chrome-extension/background.js b/assets/chrome-extension/background.js index 5ebe4008a..949565711 100644 --- a/assets/chrome-extension/background.js +++ b/assets/chrome-extension/background.js @@ -882,7 +882,18 @@ chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => { const { url, token } = msg const headers = token ? { 'x-openclaw-relay-token': token } : {} fetch(url, { method: 'GET', headers, signal: AbortSignal.timeout(2000) }) - .then((res) => sendResponse({ status: res.status, ok: res.ok })) + .then(async (res) => { + const contentType = String(res.headers.get('content-type') || '') + let json = null + if (contentType.includes('application/json')) { + try { + json = await res.json() + } catch { + json = null + } + } + sendResponse({ status: res.status, ok: res.ok, contentType, json }) + }) .catch((err) => sendResponse({ status: 0, ok: false, error: String(err) })) return true }) diff --git a/assets/chrome-extension/options.js b/assets/chrome-extension/options.js index 7a47a5d94..96b87768d 100644 --- a/assets/chrome-extension/options.js +++ b/assets/chrome-extension/options.js @@ -54,12 +54,39 @@ async function checkRelayReachable(port, token) { } if (res.error) throw new Error(res.error) if (!res.ok) throw new Error(`HTTP ${res.status}`) + + // Validate that this is a CDP relay /json/version payload, not gateway HTML. + const contentType = String(res.contentType || '') + const data = res.json + if (!contentType.includes('application/json')) { + setStatus( + 'error', + 'Wrong port: this is likely the gateway, not the relay. Use gateway port + 3 (for gateway 18789, relay is 18792).', + ) + return + } + if (!data || typeof data !== 'object' || !('Browser' in data) || !('Protocol-Version' in data)) { + setStatus( + 'error', + 'Wrong port: expected relay /json/version response. Use gateway port + 3 (for gateway 18789, relay is 18792).', + ) + return + } + setStatus('ok', `Relay reachable and authenticated at http://127.0.0.1:${port}/`) - } catch { - setStatus( - 'error', - `Relay not reachable/authenticated at http://127.0.0.1:${port}/. Start OpenClaw browser relay and verify token.`, - ) + } catch (err) { + const message = String(err || '').toLowerCase() + if (message.includes('json') || message.includes('syntax')) { + setStatus( + 'error', + 'Wrong port: this is not a relay endpoint. Use gateway port + 3 (for gateway 18789, relay is 18792).', + ) + } else { + setStatus( + 'error', + `Relay not reachable/authenticated at http://127.0.0.1:${port}/. Start OpenClaw browser relay and verify token.`, + ) + } } }