From f1464cf005a9e104afda14a12643c14a628a2ae9 Mon Sep 17 00:00:00 2001 From: Claude Bot Date: Thu, 24 Sep 2026 17:06:49 +0200 Subject: [PATCH] fix(auth): trim configured and presented API keys The workstation key in OpenBao ends with a newline, so the 64-byte key a client presents never matched the 65-byte configured value. Whitespace around a key carries no entropy and is a store artefact, not identity. Co-Authored-By: Claude Fable 5.1 --- src/Wiki.Host/Auth/ApiKeyAuthenticationHandler.cs | 4 +++- test/Wiki.Host.Tests/EndpointTests.cs | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Wiki.Host/Auth/ApiKeyAuthenticationHandler.cs b/src/Wiki.Host/Auth/ApiKeyAuthenticationHandler.cs index c44d491..64e7207 100644 --- a/src/Wiki.Host/Auth/ApiKeyAuthenticationHandler.cs +++ b/src/Wiki.Host/Auth/ApiKeyAuthenticationHandler.cs @@ -32,11 +32,13 @@ public sealed class ApiKeyAuthenticationHandler( } if (presented is null) return Task.FromResult(AuthenticateResult.NoResult()); + presented = presented.Trim(); var presentedBytes = Encoding.UTF8.GetBytes(presented); foreach (var child in configuration.GetSection("Auth:ApiKeys").GetChildren()) { - var configured = child.Value; + // Secret stores hand keys over with a trailing newline more often than not. + var configured = child.Value?.Trim(); if (string.IsNullOrEmpty(configured)) continue; if (CryptographicOperations.FixedTimeEquals(presentedBytes, Encoding.UTF8.GetBytes(configured))) { diff --git a/test/Wiki.Host.Tests/EndpointTests.cs b/test/Wiki.Host.Tests/EndpointTests.cs index e31b34a..5d3086d 100644 --- a/test/Wiki.Host.Tests/EndpointTests.cs +++ b/test/Wiki.Host.Tests/EndpointTests.cs @@ -26,6 +26,7 @@ public sealed class WikiHostFactory : WebApplicationFactory builder.UseEnvironment("Testing"); builder.UseSetting("Wiki:Webhook:Secret", WebhookSecret); builder.UseSetting("Auth:ApiKeys:tester", ApiKey); + builder.UseSetting("Auth:ApiKeys:newline", "newline-key\n"); builder.UseSetting("Auth:ReverseProxy:TrustedProxies:0", "127.0.0.1"); builder.UseSetting("Wiki:Index:File:Directory", Path.Combine(Path.GetTempPath(), "wiki-host-tests", Guid.NewGuid().ToString("N"))); builder.ConfigureServices(services => @@ -207,6 +208,10 @@ public class EndpointTests(WikiHostFactory factory) : IClassFixture