From 3c910dd64be2dc360ddf148fd1b7dcfcfc589c49 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 20 Jun 2026 18:21:14 +0200 Subject: [PATCH] fix(sharing): re-sanitize remote payloads on receipt A peer might run an older build that does not strip its own project names/sessions. Sanitize every remote payload when we receive it too, so project names never cross into our dashboard regardless of the sender's version. Aggregate numbers (cost, tokens, models, tools, daily) are kept. --- src/sharing/host.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sharing/host.ts b/src/sharing/host.ts index 5ef3f935..e098f7e5 100644 --- a/src/sharing/host.ts +++ b/src/sharing/host.ts @@ -1,9 +1,11 @@ import { hello, pair, pairRequest, fetchUsage } from './client.js' import { loadOrCreateIdentity } from './identity.js' import { pairingCode } from './pairing.js' +import { sanitizeForSharing } from './sanitize.js' import type { DiscoveredDevice } from './discovery.js' import type { UsageQuery } from './share-server.js' import { getSharingDir, loadRemotes, saveRemotes, type RemoteDevice } from './store.js' +import type { MenubarPayload } from '../menubar-json.js' import { formatCost } from '../currency.js' import { formatTokens } from '../format.js' @@ -96,7 +98,10 @@ export async function pullDevices( remotes.map(async (r): Promise => { try { const res = await fetchUsage({ identity, host: r.host, port: r.port, expectedFingerprint: r.fingerprint }, r.token, query) - if (res.status === 200) return { name: r.name, local: false, payload: res.json as DevicePayload } + // Re-sanitize on receipt: do not trust the sender to have stripped its + // own project names/sessions (it may run an older build). Belt and + // suspenders alongside the sender-side sanitize. + if (res.status === 200) return { name: r.name, local: false, payload: sanitizeForSharing(res.json as MenubarPayload) } return { name: r.name, local: false, error: res.status === 401 ? 'not authorized (re-pair?)' : `HTTP ${res.status}` } } catch (e) { return { name: r.name, local: false, error: e instanceof Error ? e.message : String(e) }