diff --git a/.changeset/player-forced-subscribe-crash.md b/.changeset/player-forced-subscribe-crash.md deleted file mode 100644 index 2d3bc2a13..000000000 --- a/.changeset/player-forced-subscribe-crash.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@epicgames-ps/lib-pixelstreamingsignalling-ue5.8': patch -'@epicgames-ps/wilbur': patch ---- - -Stop an unsubscribed player from crashing the signalling server. When a player sends a message without being subscribed, `sendToStreamer` force-subscribes it to the first available streamer and then forwards through `this.subscribedStreamer!`. `subscribe()` can decline — most commonly because `maxSubscribers` is already reached — and reports that only by leaving `subscribedStreamer` unset, so the non-null assertions throw a TypeError out of a websocket message handler and take the process down, disconnecting every other player. It now checks the subscription took, and disconnects just that player if it did not. diff --git a/.changeset/player-token-gate.md b/.changeset/player-token-gate.md deleted file mode 100644 index 35adf3965..000000000 --- a/.changeset/player-token-gate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@epicgames-ps/wilbur': minor ---- - -Add `--player_token` (or `--player_token_file`), an optional shared token that a player must present to connect. It is checked with the `playerWsOptions.verifyClient` seam the security guidelines already recommend, so a player that cannot present it is refused during the HTTP upgrade with `401` and never becomes a connection — which is what keeps the config message, and any TURN credential in its peer options, away from it. The token is accepted as a `?token=` query parameter or an `Authorization: Bearer` header, compared over SHA-256 digests so neither its length nor the position of the first difference is observable, removed from the request before the connection is logged, and kept out of `--save`, the `--log_config` dump, the `--stdin` config dump and — when `--player_token_file` is used — the process command line. Each refusal is logged with its source address, since the player port is not covered by the HTTP rate limiter. Streamer and SFU connections are unaffected, and no player connection is refused when no token is supplied. See `Docs/Security-Guidelines.md`. diff --git a/.changeset/stdin-config-dump-secrets.md b/.changeset/stdin-config-dump-secrets.md deleted file mode 100644 index 468f1c7dd..000000000 --- a/.changeset/stdin-config-dump-secrets.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@epicgames-ps/wilbur': patch ---- - -Redact `turn_secret` and `player_token` in the interactive config dump. Pressing `c` with `--stdin` wrote the whole options object to stdout, and a service supervisor routinely redirects stdout to a file — so the dump put a secret on disk just as surely as the `--log_config` dump it was already redacted in. diff --git a/.changeset/turn-ephemeral-credentials.md b/.changeset/turn-ephemeral-credentials.md deleted file mode 100644 index f078541dd..000000000 --- a/.changeset/turn-ephemeral-credentials.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@epicgames-ps/lib-pixelstreamingsignalling-ue5.8': minor -'@epicgames-ps/wilbur': minor ---- - -Allow TURN credentials to be issued per connection rather than shared by every session. `peerOptions` is static, so a credential written there is sent to every peer that ever connects and cannot be changed without a redeploy — the weakness noted in tip 3 of the security guidelines. `IServerConfig.peerOptionsProvider` is consulted once per connecting peer and returns the peer options for that peer, falling back to `peerOptions` if it throws. On top of it the signalling server adds `--turn_secret` (or `--turn_secret_file`) and `--turn_ttl`, which give every `turn:`/`turns:` entry a time limited username and credential in the form coturn's `use-auth-secret` mode expects. Default behaviour is unchanged when no secret is supplied. See `Docs/Security-Guidelines.md`.