From 44c4c9531ea265ae1d9a99750508caa414d5b113 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Tue, 28 Jul 2026 09:49:50 +0200 Subject: [PATCH] Stop splicing whole SSE buffers into error text processEventStream reported an unrecognized line separator by interpolating the entire buffer into the error string. That buffer is the full pre-filter payload -- for a tools/list, the unfiltered tool list -- and the error is logged upstream, so a backend response with no recognized separator produced one unbounded log line containing the very payload the filter exists to scrub. Report the length instead, which is the only diagnostic value the message carried. This is the byte-identical sibling of the case fixed in pkg/authz/response_filter.go by #6066. Fixing one and not the other was an oversight, not a scoping decision. Also correct a comment that contradicted its own function: it said the authorizer error "must never be promoted to a structured field routed to an aggregator beyond this log line" while the next statement logs it as exactly such a field. The intent was to forbid copying it into further log lines, not to forbid the one that is there. Co-Authored-By: Claude Opus 5 --- pkg/authz/middleware.go | 4 ++-- pkg/mcp/tool_filter.go | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pkg/authz/middleware.go b/pkg/authz/middleware.go index 667a94e474..3d9ccb4d55 100644 --- a/pkg/authz/middleware.go +++ b/pkg/authz/middleware.go @@ -140,8 +140,8 @@ func shouldSkipSubsequentAuthorization(method string) bool { // "Unauthorized" message -- err (an authorizer failure) can carry policy detail that // security.md forbids returning to callers, so it is logged server-side instead. // Cedar's evaluation context can embed decoded JWT claim values (see the claim-keys- -// only rule in authorizers/cedar/core.go), so err must never be promoted to a -// structured field routed to an aggregator beyond this log line. +// only rule in authorizers/cedar/core.go), so err must not be surfaced to the client, +// nor copied into additional log lines or fields beyond the single Warn below. func handleUnauthorized(w http.ResponseWriter, msgID interface{}, err error) { if err != nil { slog.Warn("authorization denied", "error", err) diff --git a/pkg/mcp/tool_filter.go b/pkg/mcp/tool_filter.go index 5b7b30fd70..e3446c45cd 100644 --- a/pkg/mcp/tool_filter.go +++ b/pkg/mcp/tool_filter.go @@ -697,7 +697,9 @@ func processEventStream( } else if len(buffer) >= 1 && buffer[len(buffer)-1] == '\r' { linesep = []byte("\r") } else { - return fmt.Errorf("unsupported separator: %s", string(buffer)) + // Length only, not the buffer: buffer is the full pre-filter payload + // (e.g. the unfiltered tools/list), and this error is logged upstream. + return fmt.Errorf("unsupported SSE line separator in %d-byte buffer", len(buffer)) } var linesepTotal, linesepCount int