From 4378a555d3ea09b4a55d8a4c92e9074bd4c6edc5 Mon Sep 17 00:00:00 2001 From: Gary Date: Tue, 22 Sep 2026 11:19:35 +0200 Subject: [PATCH] fix(route): keep tokens out of the access log Websocket routes take the user's token from the query string, since a browser cannot set a header on a websocket, and echo's default access log writes the request URI, query included: users' tokens went to the journal. The access log now writes the path, as the message bus does. --- route/access_log.go | 13 +++++++++++++ route/access_log_test.go | 12 ++++++++++++ route/v1.go | 2 +- route/v2.go | 2 +- 4 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 route/access_log.go create mode 100644 route/access_log_test.go diff --git a/route/access_log.go b/route/access_log.go new file mode 100644 index 0000000..417e136 --- /dev/null +++ b/route/access_log.go @@ -0,0 +1,13 @@ +package route + +import ( + "strings" + + echo_middleware "github.com/labstack/echo/v4/middleware" +) + +// accessLogFormat is echo's default access log with the path in place of the +// request URI: websocket routes take the user's token from the query string +// (a browser cannot set a header on a websocket), and it must not reach the +// journal. +var accessLogFormat = strings.Replace(echo_middleware.DefaultLoggerConfig.Format, `"uri":"${uri}"`, `"path":"${path}"`, 1) diff --git a/route/access_log_test.go b/route/access_log_test.go new file mode 100644 index 0000000..f4a52c7 --- /dev/null +++ b/route/access_log_test.go @@ -0,0 +1,12 @@ +package route + +import ( + "strings" + "testing" +) + +func TestTheAccessLogLeavesTheQueryStringOut(t *testing.T) { + if strings.Contains(accessLogFormat, "${uri}") || !strings.Contains(accessLogFormat, "${path}") { + t.Fatalf("the access log must log the path, not the URI with its query: %s", accessLogFormat) + } +} diff --git a/route/v1.go b/route/v1.go index f768795..a7f564a 100644 --- a/route/v1.go +++ b/route/v1.go @@ -28,7 +28,7 @@ func InitV1Router() http.Handler { e.Use(echo_middleware.Gzip()) e.Use(echo_middleware.Recover()) - e.Use(echo_middleware.Logger()) + e.Use(echo_middleware.LoggerWithConfig(echo_middleware.LoggerConfig{Format: accessLogFormat})) v1Group := e.Group("/v1") diff --git a/route/v2.go b/route/v2.go index b4942e3..7632da3 100644 --- a/route/v2.go +++ b/route/v2.go @@ -60,7 +60,7 @@ func InitV2Router() http.Handler { e.Use(echo_middleware.Gzip()) - e.Use(echo_middleware.Logger()) + e.Use(echo_middleware.LoggerWithConfig(echo_middleware.LoggerConfig{Format: accessLogFormat})) e.Use(echojwt.WithConfig(echojwt.Config{ Skipper: func(c echo.Context) bool {