Backend: the correlation-id gate anchors with \z

.NET's $ also matches before a final newline, so "7c9e6679\n" passed the allow-list that guards
the inbound X-Correlation-ID against CRLF and log forgery and was echoed. Such a value does not
arrive over HTTP, but the gate now holds what its comment promises; a new test case pins it
(red with $).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Oliver Kieselbach
2026-10-12 17:55:26 +02:00
parent 52f6a177f9
commit 4e519fa4b7
2 changed files with 3 additions and 1 deletions
@@ -116,6 +116,7 @@ public class CorrelationIdMiddlewareTests
"",
"7c9e6679 a1b2",
"7c9e6679\r\nX-Forged: 1",
"7c9e6679\n", // .NET's `$` also matches before a final newline; the gate anchors with `\z`
"7c9e6679.a1b2",
"7c9e6679-ä",
new string('a', 129),
@@ -26,7 +26,8 @@ public class CorrelationIdMiddleware : IFunctionsWorkerMiddleware
internal const string ExposedHeaders = "X-Correlation-ID, Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset";
// Strict allow-list gate against CRLF / log-forgery / App-Insights row-injection via inbound header.
private static readonly Regex CorrelationIdPattern = new("^[A-Za-z0-9_-]{1,128}$", RegexOptions.Compiled);
// Anchored with \z: .NET's $ also matches before a final "\n".
private static readonly Regex CorrelationIdPattern = new(@"^[A-Za-z0-9_-]{1,128}\z", RegexOptions.Compiled);
private readonly ILogger<CorrelationIdMiddleware> _logger;