improve voice chat security by implementing join validation
All checks were successful
Server Build / publish (push) Successful in 29s
Voice Build / publish (push) Successful in 24s

This commit is contained in:
olcxja 2026-08-24 15:01:32 +02:00
commit 1915198d82
7 changed files with 392 additions and 9 deletions

View file

@ -6,6 +6,14 @@ public class Program
{
public static ConcurrentDictionary<string, ConcurrentDictionary<ulong, Session>> Rooms = new ();
// Per-IP rate limit for the unauthenticated /room/users endpoint: legit
// clients poll roughly once per second while in a call, so the default of
// 120/min per IP (ROOM_USERS_RATE_LIMIT) leaves ample headroom (incl.
// several users behind one NAT) while making bulk room-enumeration scans
// impractical. Fixed 60s window: (request count, window reset unix time).
// Entries are pruned in the 1s loop below.
public static ConcurrentDictionary<string, (int count, long resetAt)> UsersListLimits = new ();
public static ulong TotalBytesSent = 0;
public static ulong TotalBytesReceived = 0;
private static ulong CurrentBandwidthKps = 0;
@ -25,6 +33,12 @@ public class Program
Interlocked.Exchange(ref TotalBytesReceived, 0);
Interlocked.Exchange(ref TotalBytesSent, 0);
CurrentBandwidthKps = (sentDelta + receivedDelta);
long nowSec = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
foreach (var entry in UsersListLimits)
{
if (entry.Value.resetAt <= nowSec) UsersListLimits.TryRemove(entry.Key, out _);
}
}
});
@ -67,6 +81,16 @@ public class Program
await context.Response.WriteAsync(Interlocked.Read(ref CurrentBandwidthKps).ToString());
return;
case "/room/users":
string callerIp = context.Connection.RemoteIpAddress?.ToString() ?? "";
long nowSec = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
var window = UsersListLimits.AddOrUpdate(callerIp,
(1, nowSec + 60),
(_, old) => old.resetAt <= nowSec ? (1, nowSec + 60) : (old.count + 1, old.resetAt));
if (window.count > Utils.ROOM_USERS_RATE_LIMIT)
{
context.Response.StatusCode = 429;
return;
}
string roomId = context.Request.Query["room"].ToString();
context.Response.ContentType = "application/json";