From 88b0e9d2921f070760842b4bafcf2eecff20da63 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Wed, 29 Jan 2025 13:07:25 -0300 Subject: [PATCH] errorFilteredFallbackClient: avoids leaking URL in fallback client --- arbitrum/apibackend.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/arbitrum/apibackend.go b/arbitrum/apibackend.go index d00346d48..49a60ef36 100644 --- a/arbitrum/apibackend.go +++ b/arbitrum/apibackend.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "math/big" + "net/url" "strconv" "strings" "time" @@ -51,6 +52,22 @@ type APIBackend struct { sync SyncProgressBackend } +type errorFilteredFallbackClient struct { + impl types.FallbackClient + url string +} + +func (c *errorFilteredFallbackClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error { + err := c.impl.CallContext(ctx, result, method, args...) + if err != nil && strings.Contains(err.Error(), c.url) { + // avoids leaking the URL in the error message. + // URL can contain sensitive information such as API keys. + log.Warn("fallback client error", "error", err) + return errors.New("Failed to call fallback API") + } + return err +} + type timeoutFallbackClient struct { impl types.FallbackClient timeout time.Duration @@ -77,12 +94,22 @@ func CreateFallbackClient(fallbackClientUrl string, fallbackClientTimeout time.D types.SetFallbackError(strings.Join(fields, ":"), int(errNumber)) return nil, nil } + var fallbackClient types.FallbackClient var err error fallbackClient, err = rpc.Dial(fallbackClientUrl) if err != nil { return nil, fmt.Errorf("failed creating fallback connection: %w", err) } + url, err := url.Parse(fallbackClientUrl) + if err != nil { + return nil, fmt.Errorf("failed parsing fallback URL: %w", err) + } + fallbackClient = &errorFilteredFallbackClient{ + impl: fallbackClient, + url: url.String(), + } + if fallbackClientTimeout != 0 { fallbackClient = &timeoutFallbackClient{ impl: fallbackClient,