From 05e71d4c6b31c9af015f0e9db204b034e91e8e49 Mon Sep 17 00:00:00 2001 From: Jo Date: Mon, 22 May 2023 13:27:28 +0200 Subject: [PATCH] AnonymousAuth: Fix concurrent read-write crash (#68637) clone http req before tagging --- pkg/services/authn/clients/anonymous.go | 10 +++++++++- pkg/services/contexthandler/contexthandler.go | 9 ++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/pkg/services/authn/clients/anonymous.go b/pkg/services/authn/clients/anonymous.go index bd29a1eab04..d42d4717fd4 100644 --- a/pkg/services/authn/clients/anonymous.go +++ b/pkg/services/authn/clients/anonymous.go @@ -2,6 +2,7 @@ package clients import ( "context" + "net/http" "strings" "github.com/grafana/grafana/pkg/infra/log" @@ -40,13 +41,20 @@ func (a *Anonymous) Authenticate(ctx context.Context, r *authn.Request) (*authn. return nil, err } + httpReqCopy := &http.Request{} + if r.HTTPRequest != nil && r.HTTPRequest.Header != nil { + // avoid r.HTTPRequest.Clone(context.Background()) as we do not require a full clone + httpReqCopy.Header = r.HTTPRequest.Header.Clone() + httpReqCopy.RemoteAddr = r.HTTPRequest.RemoteAddr + } + go func() { defer func() { if err := recover(); err != nil { a.log.Warn("tag anon session panic", "err", err) } }() - if err := a.anonSessionService.TagSession(context.Background(), r.HTTPRequest); err != nil { + if err := a.anonSessionService.TagSession(context.Background(), httpReqCopy); err != nil { a.log.Warn("failed to tag anonymous session", "error", err) } }() diff --git a/pkg/services/contexthandler/contexthandler.go b/pkg/services/contexthandler/contexthandler.go index 6ba160c8e39..9ceecdf049b 100644 --- a/pkg/services/contexthandler/contexthandler.go +++ b/pkg/services/contexthandler/contexthandler.go @@ -237,13 +237,20 @@ func (h *ContextHandler) initContextWithAnonymousUser(reqContext *contextmodel.R return false } + httpReqCopy := &http.Request{} + if reqContext.Req != nil && reqContext.Req.Header != nil { + // avoid r.HTTPRequest.Clone(context.Background()) as we do not require a full clone + httpReqCopy.Header = reqContext.Req.Header.Clone() + httpReqCopy.RemoteAddr = reqContext.Req.RemoteAddr + } + go func() { defer func() { if err := recover(); err != nil { reqContext.Logger.Warn("tag anon session panic", "err", err) } }() - if err := h.anonSessionService.TagSession(context.Background(), reqContext.Req); err != nil { + if err := h.anonSessionService.TagSession(context.Background(), httpReqCopy); err != nil { reqContext.Logger.Warn("Failed to tag anonymous session", "error", err) } }()