From 4558eef4465ec2dff6fad7faaa0ca6adb00aa25f Mon Sep 17 00:00:00 2001 From: entity0xfe <109791748+entity0xfe@users.noreply.github.com> Date: Sat, 4 Mar 2023 12:16:57 +0100 Subject: [PATCH] lib/discover: Don't leak relay-tokens to discovery (#8762) Use an allowlist to send only the `id` query param to the discovery server. --- lib/discover/global.go | 9 +++++++++ lib/discover/local.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/lib/discover/global.go b/lib/discover/global.go index b1937efd7..be143b990 100644 --- a/lib/discover/global.go +++ b/lib/discover/global.go @@ -54,6 +54,15 @@ type announcement struct { Addresses []string `json:"addresses"` } +func (a announcement) MarshalJSON() ([]byte, error) { + type announcementCopy announcement + + a.Addresses = sanitizeRelayAddresses(a.Addresses) + + aCopy := announcementCopy(a) + return json.Marshal(aCopy) +} + type serverOptions struct { insecure bool // don't check certificate noAnnounce bool // don't announce diff --git a/lib/discover/local.go b/lib/discover/local.go index e70e8509c..ba950f441 100644 --- a/lib/discover/local.go +++ b/lib/discover/local.go @@ -116,6 +116,9 @@ func (c *localClient) announcementPkt(instanceID int64, msg []byte) ([]byte, boo // usable as-is. addrs = filterUnspecifiedLocal(addrs) + // do not leak relay tokens to discovery + addrs = sanitizeRelayAddresses(addrs) + if len(addrs) == 0 { // Nothing to announce return msg, false @@ -315,3 +318,32 @@ func filterUnspecifiedLocal(addrs []string) []string { } return filtered } + +func sanitizeRelayAddresses(addrs []string) []string { + filtered := addrs[:0] + allowlist := []string{"id"} + + for _, addr := range addrs { + u, err := url.Parse(addr) + if err != nil { + continue + } + + if u.Scheme == "relay" { + s := url.Values{} + q := u.Query() + + for _, w := range allowlist { + if q.Has(w) { + s.Add(w, q.Get(w)) + } + } + + u.RawQuery = s.Encode() + addr = u.String() + } + + filtered = append(filtered, addr) + } + return filtered +}