mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-02-09 23:55:10 -05:00
Remove server API key fallback for client requests
SECURITY FIX: Stop using server API key when clients don't provide auth Before: If client sent no auth → proxy used server API key → gave them access After: If client sends no auth → proxy sends no auth → Jellyfin rejects (401) This ensures: - Unauthenticated users can't piggyback on server credentials - All actions are properly attributed to the actual user - Jellyfin's auth system works as intended - Server API key only used for internal operations (images, library detection) Updated test to reflect new behavior: GetJsonAsync without client headers should NOT add any authentication.
This commit is contained in:
@@ -85,7 +85,7 @@ public class JellyfinProxyServiceTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetJsonAsync_IncludesAuthHeader()
|
public async Task GetJsonAsync_WithoutClientHeaders_SendsNoAuth()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
HttpRequestMessage? captured = null;
|
HttpRequestMessage? captured = null;
|
||||||
@@ -102,13 +102,10 @@ public class JellyfinProxyServiceTests
|
|||||||
// Act
|
// Act
|
||||||
await _service.GetJsonAsync("Items");
|
await _service.GetJsonAsync("Items");
|
||||||
|
|
||||||
// Assert
|
// Assert - Should NOT include auth when no client headers provided
|
||||||
Assert.NotNull(captured);
|
Assert.NotNull(captured);
|
||||||
Assert.True(captured!.Headers.Contains("Authorization"));
|
Assert.False(captured!.Headers.Contains("Authorization"));
|
||||||
var authHeader = captured.Headers.GetValues("Authorization").First();
|
Assert.False(captured.Headers.Contains("X-Emby-Authorization"));
|
||||||
Assert.Contains("MediaBrowser", authHeader);
|
|
||||||
Assert.Contains(_settings.ApiKey!, authHeader);
|
|
||||||
Assert.Contains(_settings.ClientName!, authHeader);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|||||||
@@ -205,18 +205,11 @@ public class JellyfinProxyService
|
|||||||
_logger.LogWarning("✗ No client headers provided for {Url}", url);
|
_logger.LogWarning("✗ No client headers provided for {Url}", url);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use API key if no valid client auth was found
|
// DO NOT use server API key as fallback - let Jellyfin handle unauthenticated requests
|
||||||
|
// If client doesn't provide auth, they get what they deserve (401 from Jellyfin)
|
||||||
if (!authHeaderAdded)
|
if (!authHeaderAdded)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(_settings.ApiKey))
|
_logger.LogInformation("No client auth provided for {Url} - forwarding without auth", url);
|
||||||
{
|
|
||||||
request.Headers.Add("Authorization", GetAuthorizationHeader());
|
|
||||||
_logger.LogInformation("→ Using API key for {Url}", url);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.LogWarning("✗ No authentication available for {Url} - request will fail", url);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||||
@@ -333,16 +326,12 @@ public class JellyfinProxyService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For non-auth requests without headers, use API key
|
// DO NOT use server credentials as fallback
|
||||||
// For auth requests, client MUST provide their own client info
|
// Exception: For auth endpoints, client provides their own credentials in the body
|
||||||
if (!authHeaderAdded && !endpoint.Contains("Authenticate", StringComparison.OrdinalIgnoreCase))
|
// For all other endpoints, if client doesn't provide auth, let Jellyfin reject it
|
||||||
|
if (!authHeaderAdded)
|
||||||
{
|
{
|
||||||
var clientAuthHeader = $"MediaBrowser Client=\"{_settings.ClientName}\", " +
|
_logger.LogInformation("No client auth provided for POST {Url} - forwarding without auth", url);
|
||||||
$"Device=\"{_settings.DeviceName}\", " +
|
|
||||||
$"DeviceId=\"{_settings.DeviceId}\", " +
|
|
||||||
$"Version=\"{_settings.ClientVersion}\"";
|
|
||||||
request.Headers.TryAddWithoutValidation("X-Emby-Authorization", clientAuthHeader);
|
|
||||||
_logger.LogDebug("Using server API key for non-auth request");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||||
|
|||||||
Reference in New Issue
Block a user