Skip to content

Security: FoggyBytes/StreamLight

SECURITY.md

Security Policy

Supported versions

Only the latest release on the Releases page receives fixes. StreamLight updates itself from Settings → About, so there is no reason to stay on an older version.

Reporting a vulnerability

Please do not open a public issue for a security problem.

Report it privately through GitHub: Report a vulnerability (Security tab → Report a vulnerability). Include the version, what an attacker can do, and the steps to reproduce it.

StreamLight is maintained by one person, so there is no fixed response time — but a security report is read before anything else, and you will get an answer in the advisory thread. Fixes ship as a normal release, with the advisory published once users have had the update available.

If the problem is in the streaming protocol or the decoder pipeline that StreamLight shares with Moonlight, it most likely affects Moonlight too: report it there as well.

How StreamLight is put together

StreamLight is a fork of Moonlight-Qt (GPL v3). Knowing which parts are ours helps to judge where a problem lives:

  • Streaming protocol and decoders — moonlight-common-c, FFmpeg, D3D11VA/DXVA2, libplacebo — are upstream Moonlight's, plus Nonary's VRR pacing and PyroWave codec, imported unchanged. Upstream's security fixes are carried over as they land.
  • Third-party DLLs — the 13 libraries in the install folder (FFmpeg, SDL, OpenSSL, opus, dav1d, libplacebo, discord-rpc) are the signed copies from the official Moonlight release with the same library versions, byte for byte; the Qt DLLs and plugins are signed by The Qt Company. See libs/README.md.
  • Ours — the interface, StreamLight.exe's application code, the bridge to StreamTweak, the self-updater and the installer.

Security-relevant design

AntiHooking.dll

The name sounds alarming; what it does is narrow and defensive. AntiHooking.dll is Moonlight's own module, identical to upstream's (same file, same Git blob as moonlight-qt/AntiHooking/antihookingprotection.cpp), and it ships with the official Moonlight client too.

It is loaded by StreamLight.exe only, inside its own process, and it intercepts that process's LoadLibrary* calls to refuse a short, fixed list of DLLs that third-party software injects into every program and that are known to crash or deadlock video playback:

  • the on-screen-display DLLs of A-Volute Nahimic / ASUS Sonic Studio / SteelSeries audio suites (deadlock in D3D9 fullscreen — moonlight-qt#102);
  • EZFRD32/64.dll, seen in many crash reports;
  • the legacy Optimus hybrid-graphics shim DLLs (crash in PresentEx — moonlight-qt#386).

It does not hide StreamLight from anything, does not touch other processes, and does not interfere with security software: it only stops StreamLight itself from loading those specific files.

The bridge to StreamTweak (TCP 47998)

When the host runs StreamTweak, StreamLight talks to it on TCP port 47998 over the local network.

  • Every command is signed (RSA-SHA256, PKCS#1 v1.5) with StreamLight's existing Moonlight client certificate — the same key pair that is generated on the PC at first launch and used to pair with Sunshine. The signature covers the client id, a timestamp and the command; the host checks it against the certificate it approved, rejects timestamps outside ±60 seconds and rejects replays.
  • A client is approved once, by a person at the host: StreamLight sends its certificate and a 4-digit PIN that is shown on both screens, and StreamTweak asks its user to compare and approve. Nothing is trusted on first contact alone.
  • Commands that act on the host — power, Windows Update, link speed, clipboard — are refused unless the signature verifies.
  • The StreamTweak section (8.0.0, with StreamTweak 10.0.0) changes the host's settings only through three fixed switches — a managed app on or off, spatial audio, NVIDIA Sentinel's auto-restore — and StreamLight refuses to send anything else in their place. No path or command line leaves this device. The host accepts them only from a device it has given Host management, on top of the signature. Its Sessions tab only reads, with four fixed requests StreamLight checks before sending.
  • Streaming never depends on the bridge. Without an approved bridge StreamLight is an ordinary Moonlight client.

Shared clipboard (off by default)

When both sides turn it on, clipboard text travels over the bridge encrypted with AES-256-GCM under a key made fresh for each stream. The key is generated by the host and sent to the client wrapped with RSA-OAEP for the client's certificate; it is discarded when the stream ends. No hash or other derivative of the plaintext is ever sent. Text that password managers mark as sensitive is cleared on the other side when it is cleared at its source, and after 60 seconds at most.

Self-update

The updater looks up the latest release through the GitHub API and downloads the installer asset from GitHub. It refuses to run any installer without a SHA-256 digest published by GitHub for that asset, checks the downloaded file against it, and checks it again immediately before launching it. The installer runs visibly; nothing is installed silently.

Local data

Settings, paired hosts and the client certificate's private key are stored per Windows user in HKCU\Software\FoggyBytes\StreamLight. Logs, crash dumps and the cover cache stay on the PC (folders listed in Settings → About) and are never uploaded. See PRIVACY.md.

Installer

The installer is built with Inno Setup on GitHub Actions from this repository (.github/workflows/build-windows.yml); release assets carry a SHA-256 digest on the release page. It installs to Program Files, installs the Microsoft Visual C++ runtime when the one on the PC is older than required, and includes an uninstaller (Settings → Apps).

There aren't any published security advisories