Do not open a public issue for a suspected vulnerability. Use GitHub's private security advisory flow for this repository. Include the affected version or commit, deployment topology, reproduction steps, impact, and any suggested mitigation. Do not include real API keys, TURN credentials, certificates, user data, or third-party media.
Maintainers will acknowledge a complete report as soon as practical, validate the impact, coordinate a fix and disclosure timeline, and publish remediation for supported releases. Public disclosure should wait until a fix is available.
Security fixes target the latest release and the current main branch. Older
prototype releases are not maintained unless a release notice says otherwise.
- Set a strong, randomly generated
TRACKER_API_KEYand rotate it if exposed. - Set a separate
PEER_SESSION_SECRETof at least 32 random bytes. Never reuse the administrator API key as the session-signing secret. - Terminate TLS at a trusted reverse proxy in front of the tracker and origin.
Set
TRUST_PROXY_HOPSto the number of proxies so per-client rate and connection limits apply to viewers instead of to the proxy, and make sure the tracker is reachable only through that proxy chain; otherwise clients could choose their ownX-Forwarded-Foraddress. Protect private keys with filesystem permissions and never bake them into container images. - Use
wss://andhttps://for traffic outside a trusted development network. - Operate an authenticated TURN service for production; public STUN provides
discovery, not confidentiality or relay authorization. Prefer
TURN_URLS/TURN_SHARED_SECRETon the tracker, which issues per-peer credentials that expire shortly after the session, over static TURN passwords in client code, and keep the shared secret out of browsers and peers. - Peer joins are open to any client, so anyone who can join can obtain relay
credentials. Harden the TURN server accordingly: deny relaying to private and
loopback ranges (coturn
denied-peer-ip), and set per-user allocation and bandwidth quotas (user-quota,total-quota,max-bps). - Restrict tracker, origin, peer upload, dashboard, and metrics ports with
firewalls or Kubernetes
NetworkPolicyresources. - Keep request, peer, upload, and connection limits enabled. Size them against measured capacity rather than disabling them during overload.
- Persist SQLite on protected storage, back it up consistently, and restrict access to the database, WAL, and shared-memory files.
- Treat peer addresses, metadata, and traffic statistics as untrusted input.
Peer addresses are visible to other viewers: keep neighbor views enabled
(
TRACKER_NEIGHBOR_VIEW_SIZE) so each viewer sees only its neighbors, over both WebSocket and REST, rather than the whole audience. - Peers fetch from addresses other peers advertise. The tracker rejects
loopback, unspecified, and link-local peer addresses (including
IPv4-mapped IPv6 forms such as
[::ffff:169.254.169.254]), and Node peers also refuse host names that resolve to them. Private ranges stay allowed for LAN and container deployments, so restrict Node peers' egress (for example with aNetworkPolicy) if they run next to private services that should not receive their requests. - Monitor authentication failures, rate-limit responses, integrity failures, fallback spikes, peer churn, and unexpected origin traffic.
- Keep Node.js, FFmpeg, container base images, and npm dependencies patched.
SHA-256 sidecars detect corrupted segment bytes; they do not authenticate the content publisher unless the sidecar itself is delivered through a trusted, authenticated channel. Peers share only segments that matched a sidecar: when an origin segment's sidecar cannot be fetched, the browser SDK plays the origin bytes (as the player would without OpenStreamGrid) but never caches or shares them. Peer metadata is limited to a few short entries (32 entries, 4096 characters) because the tracker relays it to other peers, and a Node peer drops uploads to clients that stop reading after 10 s, so idle connections cannot hold its upload slots. The administrator API key is deployment-wide. Peer sessions are short-lived and identity-scoped, but they do not replace viewer account authorization in the integrating service. The development Docker Compose topology is not a hardened internet-facing deployment.