Key active sessions by user to prevent session takeover

This commit is contained in:
Shadowghost
2026-08-14 13:47:45 +02:00
parent dd7de41878
commit b1e3cf1341
@@ -309,7 +309,7 @@ namespace Emby.Server.Implementations.Session
{
if (!session.SessionControllers.Any(i => i.IsSessionActive))
{
var key = GetSessionKey(session.Client, session.DeviceId);
var key = GetSessionKey(session.Client, session.DeviceId, session.UserId);
_activeConnections.TryRemove(key, out _);
if (!string.IsNullOrEmpty(session.PlayState?.LiveStreamId))
@@ -369,7 +369,7 @@ namespace Emby.Server.Implementations.Session
if (session is not null)
{
var key = GetSessionKey(session.Client, session.DeviceId);
var key = GetSessionKey(session.Client, session.DeviceId, session.UserId);
_activeConnections.TryRemove(key, out _);
@@ -475,8 +475,11 @@ namespace Emby.Server.Implementations.Session
}
}
private static string GetSessionKey(string appName, string deviceId)
=> appName + deviceId;
// The user is part of the key because the client name and the device id are taken from the
// request headers and are not bound to the access token. Without it, any authenticated user
// could claim another user's client/device pair and take over their session.
private static string GetSessionKey(string appName, string deviceId, Guid userId)
=> appName + deviceId + userId.ToString("N", CultureInfo.InvariantCulture);
/// <summary>
/// Gets the connection.
@@ -500,7 +503,7 @@ namespace Emby.Server.Implementations.Session
ArgumentException.ThrowIfNullOrEmpty(deviceId);
var key = GetSessionKey(appName, deviceId);
var key = GetSessionKey(appName, deviceId, user?.Id ?? Guid.Empty);
SessionInfo newSession = CreateSessionInfo(key, appName, appVersion, deviceId, deviceName, remoteEndPoint, user);
SessionInfo sessionInfo = _activeConnections.GetOrAdd(key, newSession);
if (ReferenceEquals(newSession, sessionInfo))