From 689ed339112720c62707a5d5238ff797fd4e5bde Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Sun, 6 Mar 2022 14:47:23 +0000 Subject: [PATCH 01/10] Patch for CVE-2022-0870 https://huntr.dev/bounties/327797d7-ae41-498f-9bff-cc0bf98cf531/ --- internal/route/repo/webhook.go | 40 ++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/internal/route/repo/webhook.go b/internal/route/repo/webhook.go index 4314882206a..cf6d286d68e 100644 --- a/internal/route/repo/webhook.go +++ b/internal/route/repo/webhook.go @@ -8,6 +8,7 @@ import ( "fmt" "net/http" "net/url" + "net" "strings" "github.com/gogs/git-module" @@ -119,17 +120,42 @@ func WebhooksNew(c *context.Context, orCtx *orgRepoContext) { } var localHostnames = []string{ - "localhost", - "127.0.0.1", - "::1", - "0:0:0:0:0:0:0:1", +// https://datatracker.ietf.org/doc/html/rfc5735: + "127.0.0.0/8", // Loopback + "0.0.0.0/8", // "This" network + "100.64.0.0/10", // Shared address space + "169.254.0.0/16", // Link local + "172.16.0.0/12", // Private-use networks + "192.0.0.0/24", // IETF Protocol assignments + "192.0.2.0/24", // TEST-NET-1 + "192.88.99.0/24", // 6to4 Relay anycast + "192.168.0.0/16", // Private-use networks + "198.18.0.0/15", // Network interconnect + "198.51.100.0/24", // TEST-NET-2 + "203.0.113.0/24", // TEST-NET-3 + "255.255.255.255/32", // Limited broadcast + +// https://datatracker.ietf.org/doc/html/rfc1918: + "10.0.0.0/8", // Private-use networks + +// https://datatracker.ietf.org/doc/html/rfc6890: + "::1/128", // Loopback + "FC00::/7", // Unique local address + "FE80::/10", // Multicast address } // isLocalHostname returns true if given hostname is a known local address. func isLocalHostname(hostname string) bool { - for _, local := range localHostnames { - if hostname == local { - return true + resolvedAddress, dnsError := net.LookupIP(host) + if dnsError != nil { + return true + } + for _, iterativeAddress := range resolvedAddress { + for _, localRangeStr := range localHostnames { + _, localRange, _ := net.ParseCIDR(localRangeStr) + if localRange.Contains(iterativeAddress) { + return true + } } } return false From 43e424648eefaa98360809fbb08cd785d6417cf4 Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Sun, 6 Mar 2022 14:55:29 +0000 Subject: [PATCH 02/10] Added SSRF test cases --- internal/route/repo/webhook_test.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/route/repo/webhook_test.go b/internal/route/repo/webhook_test.go index 182c6eed7ea..37ac36365eb 100644 --- a/internal/route/repo/webhook_test.go +++ b/internal/route/repo/webhook_test.go @@ -22,8 +22,13 @@ func Test_isLocalHostname(t *testing.T) { {hostname: "127.0.0.1", want: true}, {hostname: "::1", want: true}, {hostname: "0:0:0:0:0:0:0:1", want: true}, - + {hostname: "fuf.me", want: true}, // Resolves to 127.0.0.1 + {hostname: "127.0.0.95", want: true}, + {hostname: "0.0.0.0", want: true}, + {hostname: "192.168.123.45", want: true}, + {hostname: "gogs.io", want: false}, + {hostname: "google.com", want: false} } for _, test := range tests { t.Run("", func(t *testing.T) { From 9c800c846062190bcd94a939a19b1e400332c09e Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Mon, 7 Mar 2022 16:27:11 +0000 Subject: [PATCH 03/10] Corrected variable naming This should fix: ``Error: internal/route/repo/webhook.go:149:44: undefined: host`` --- internal/route/repo/webhook.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/route/repo/webhook.go b/internal/route/repo/webhook.go index cf6d286d68e..41fbebbb7a1 100644 --- a/internal/route/repo/webhook.go +++ b/internal/route/repo/webhook.go @@ -146,7 +146,7 @@ var localHostnames = []string{ // isLocalHostname returns true if given hostname is a known local address. func isLocalHostname(hostname string) bool { - resolvedAddress, dnsError := net.LookupIP(host) + resolvedAddress, dnsError := net.LookupIP(hostname) if dnsError != nil { return true } From 40bbd3fd61a04d74da2151362bb2d1baa19e8dc4 Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Mon, 7 Mar 2022 16:27:55 +0000 Subject: [PATCH 04/10] Removed comment in Test_isLocalHostname case This should fix: ``Error: internal/route/repo/webhook_test.go:31:40: missing ',' before newline in composite literal`` --- internal/route/repo/webhook_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/route/repo/webhook_test.go b/internal/route/repo/webhook_test.go index 37ac36365eb..acbd69a311e 100644 --- a/internal/route/repo/webhook_test.go +++ b/internal/route/repo/webhook_test.go @@ -22,7 +22,7 @@ func Test_isLocalHostname(t *testing.T) { {hostname: "127.0.0.1", want: true}, {hostname: "::1", want: true}, {hostname: "0:0:0:0:0:0:0:1", want: true}, - {hostname: "fuf.me", want: true}, // Resolves to 127.0.0.1 + {hostname: "fuf.me", want: true}, {hostname: "127.0.0.95", want: true}, {hostname: "0.0.0.0", want: true}, {hostname: "192.168.123.45", want: true}, From c78547831c390688fcc4cdc58921cbf7fc31b3b4 Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Mon, 7 Mar 2022 17:32:56 +0000 Subject: [PATCH 05/10] Added comma to last test item --- internal/route/repo/webhook_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/route/repo/webhook_test.go b/internal/route/repo/webhook_test.go index acbd69a311e..3f5cf46df76 100644 --- a/internal/route/repo/webhook_test.go +++ b/internal/route/repo/webhook_test.go @@ -28,7 +28,7 @@ func Test_isLocalHostname(t *testing.T) { {hostname: "192.168.123.45", want: true}, {hostname: "gogs.io", want: false}, - {hostname: "google.com", want: false} + {hostname: "google.com", want: false}, } for _, test := range tests { t.Run("", func(t *testing.T) { From 7f64edb0f3872db40a09b51da527d3af29d33abe Mon Sep 17 00:00:00 2001 From: Joe Chen Date: Tue, 8 Mar 2022 11:06:49 +0800 Subject: [PATCH 06/10] gofmt --- internal/route/repo/webhook.go | 46 +++++++++++++++++----------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/internal/route/repo/webhook.go b/internal/route/repo/webhook.go index 41fbebbb7a1..4fcb2c106df 100644 --- a/internal/route/repo/webhook.go +++ b/internal/route/repo/webhook.go @@ -120,27 +120,27 @@ func WebhooksNew(c *context.Context, orCtx *orgRepoContext) { } var localHostnames = []string{ -// https://datatracker.ietf.org/doc/html/rfc5735: - "127.0.0.0/8", // Loopback - "0.0.0.0/8", // "This" network - "100.64.0.0/10", // Shared address space - "169.254.0.0/16", // Link local - "172.16.0.0/12", // Private-use networks - "192.0.0.0/24", // IETF Protocol assignments - "192.0.2.0/24", // TEST-NET-1 - "192.88.99.0/24", // 6to4 Relay anycast - "192.168.0.0/16", // Private-use networks - "198.18.0.0/15", // Network interconnect - "198.51.100.0/24", // TEST-NET-2 - "203.0.113.0/24", // TEST-NET-3 + // https://datatracker.ietf.org/doc/html/rfc5735: + "127.0.0.0/8", // Loopback + "0.0.0.0/8", // "This" network + "100.64.0.0/10", // Shared address space + "169.254.0.0/16", // Link local + "172.16.0.0/12", // Private-use networks + "192.0.0.0/24", // IETF Protocol assignments + "192.0.2.0/24", // TEST-NET-1 + "192.88.99.0/24", // 6to4 Relay anycast + "192.168.0.0/16", // Private-use networks + "198.18.0.0/15", // Network interconnect + "198.51.100.0/24", // TEST-NET-2 + "203.0.113.0/24", // TEST-NET-3 "255.255.255.255/32", // Limited broadcast - -// https://datatracker.ietf.org/doc/html/rfc1918: + + // https://datatracker.ietf.org/doc/html/rfc1918: "10.0.0.0/8", // Private-use networks - -// https://datatracker.ietf.org/doc/html/rfc6890: - "::1/128", // Loopback - "FC00::/7", // Unique local address + + // https://datatracker.ietf.org/doc/html/rfc6890: + "::1/128", // Loopback + "FC00::/7", // Unique local address "FE80::/10", // Multicast address } @@ -152,10 +152,10 @@ func isLocalHostname(hostname string) bool { } for _, iterativeAddress := range resolvedAddress { for _, localRangeStr := range localHostnames { - _, localRange, _ := net.ParseCIDR(localRangeStr) - if localRange.Contains(iterativeAddress) { - return true - } + _, localRange, _ := net.ParseCIDR(localRangeStr) + if localRange.Contains(iterativeAddress) { + return true + } } } return false From a6a0417b4f6e9d59e18a49b01b7c626ab9032b3e Mon Sep 17 00:00:00 2001 From: Joe Chen Date: Tue, 8 Mar 2022 11:15:42 +0800 Subject: [PATCH 07/10] Parse CIDRs at init time --- internal/route/repo/webhook.go | 78 +++++++++++++++++------------ internal/route/repo/webhook_test.go | 7 +-- 2 files changed, 49 insertions(+), 36 deletions(-) diff --git a/internal/route/repo/webhook.go b/internal/route/repo/webhook.go index 4fcb2c106df..246b0375f14 100644 --- a/internal/route/repo/webhook.go +++ b/internal/route/repo/webhook.go @@ -6,9 +6,9 @@ package repo import ( "fmt" + "net" "net/http" "net/url" - "net" "strings" "github.com/gogs/git-module" @@ -119,41 +119,53 @@ func WebhooksNew(c *context.Context, orCtx *orgRepoContext) { c.Success(orCtx.TmplNew) } -var localHostnames = []string{ - // https://datatracker.ietf.org/doc/html/rfc5735: - "127.0.0.0/8", // Loopback - "0.0.0.0/8", // "This" network - "100.64.0.0/10", // Shared address space - "169.254.0.0/16", // Link local - "172.16.0.0/12", // Private-use networks - "192.0.0.0/24", // IETF Protocol assignments - "192.0.2.0/24", // TEST-NET-1 - "192.88.99.0/24", // 6to4 Relay anycast - "192.168.0.0/16", // Private-use networks - "198.18.0.0/15", // Network interconnect - "198.51.100.0/24", // TEST-NET-2 - "203.0.113.0/24", // TEST-NET-3 - "255.255.255.255/32", // Limited broadcast - - // https://datatracker.ietf.org/doc/html/rfc1918: - "10.0.0.0/8", // Private-use networks - - // https://datatracker.ietf.org/doc/html/rfc6890: - "::1/128", // Loopback - "FC00::/7", // Unique local address - "FE80::/10", // Multicast address +var localCIDRs []*net.IPNet + +func init() { + // Parsing hardcoded CIDR strings should never fail, if in case it does, let's + // fail it at start. + rawCIDRs := []string{ + // https://datatracker.ietf.org/doc/html/rfc5735: + "127.0.0.0/8", // Loopback + "0.0.0.0/8", // "This" network + "100.64.0.0/10", // Shared address space + "169.254.0.0/16", // Link local + "172.16.0.0/12", // Private-use networks + "192.0.0.0/24", // IETF Protocol assignments + "192.0.2.0/24", // TEST-NET-1 + "192.88.99.0/24", // 6to4 Relay anycast + "192.168.0.0/16", // Private-use networks + "198.18.0.0/15", // Network interconnect + "198.51.100.0/24", // TEST-NET-2 + "203.0.113.0/24", // TEST-NET-3 + "255.255.255.255/32", // Limited broadcast + + // https://datatracker.ietf.org/doc/html/rfc1918: + "10.0.0.0/8", // Private-use networks + + // https://datatracker.ietf.org/doc/html/rfc6890: + "::1/128", // Loopback + "FC00::/7", // Unique local address + "FE80::/10", // Multicast address + } + for _, raw := range rawCIDRs { + _, cidr, err := net.ParseCIDR(raw) + if err != nil { + panic(fmt.Sprintf("parse CIDR %q: %v", raw, err)) + } + localCIDRs = append(localCIDRs, cidr) + } } -// isLocalHostname returns true if given hostname is a known local address. -func isLocalHostname(hostname string) bool { - resolvedAddress, dnsError := net.LookupIP(hostname) - if dnsError != nil { +// IsLocalHostname returns true if given hostname is a known local address. +func IsLocalHostname(hostname string) bool { + ips, err := net.LookupIP(hostname) + if err != nil { return true } - for _, iterativeAddress := range resolvedAddress { - for _, localRangeStr := range localHostnames { - _, localRange, _ := net.ParseCIDR(localRangeStr) - if localRange.Contains(iterativeAddress) { + for _, ip := range ips { + for _, cidr := range localCIDRs { + if cidr.Contains(ip) { return true } } @@ -170,7 +182,7 @@ func validateWebhook(actor *db.User, l macaron.Locale, w *db.Webhook) (field, ms return "PayloadURL", l.Tr("repo.settings.webhook.err_cannot_parse_payload_url", err), false } - if isLocalHostname(payloadURL.Hostname()) { + if IsLocalHostname(payloadURL.Hostname()) { return "PayloadURL", l.Tr("repo.settings.webhook.err_cannot_use_local_addresses"), false } } diff --git a/internal/route/repo/webhook_test.go b/internal/route/repo/webhook_test.go index 3f5cf46df76..30886e988d4 100644 --- a/internal/route/repo/webhook_test.go +++ b/internal/route/repo/webhook_test.go @@ -13,7 +13,7 @@ import ( "gogs.io/gogs/internal/mocks" ) -func Test_isLocalHostname(t *testing.T) { +func TestIsLocalHostname(t *testing.T) { tests := []struct { hostname string want bool @@ -26,13 +26,14 @@ func Test_isLocalHostname(t *testing.T) { {hostname: "127.0.0.95", want: true}, {hostname: "0.0.0.0", want: true}, {hostname: "192.168.123.45", want: true}, - + {hostname: "gogs.io", want: false}, {hostname: "google.com", want: false}, + {hostname: "165.232.140.255", want: false}, } for _, test := range tests { t.Run("", func(t *testing.T) { - assert.Equal(t, test.want, isLocalHostname(test.hostname)) + assert.Equal(t, test.want, IsLocalHostname(test.hostname)) }) } } From 7f7939b2e65702a26a9947192ba6c66417bff021 Mon Sep 17 00:00:00 2001 From: Joe Chen Date: Tue, 8 Mar 2022 11:20:56 +0800 Subject: [PATCH 08/10] Move to netutil --- internal/netutil/netutil.go | 64 +++++++++++++++++++++++++++++ internal/netutil/netutil_test.go | 36 ++++++++++++++++ internal/route/repo/webhook.go | 58 +------------------------- internal/route/repo/webhook_test.go | 25 ----------- 4 files changed, 102 insertions(+), 81 deletions(-) create mode 100644 internal/netutil/netutil.go create mode 100644 internal/netutil/netutil_test.go diff --git a/internal/netutil/netutil.go b/internal/netutil/netutil.go new file mode 100644 index 00000000000..e3b3b8cc5c4 --- /dev/null +++ b/internal/netutil/netutil.go @@ -0,0 +1,64 @@ +// Copyright 2022 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package netutil + +import ( + "fmt" + "net" +) + +var localCIDRs []*net.IPNet + +func init() { + // Parsing hardcoded CIDR strings should never fail, if in case it does, let's + // fail it at start. + rawCIDRs := []string{ + // https://datatracker.ietf.org/doc/html/rfc5735: + "127.0.0.0/8", // Loopback + "0.0.0.0/8", // "This" network + "100.64.0.0/10", // Shared address space + "169.254.0.0/16", // Link local + "172.16.0.0/12", // Private-use networks + "192.0.0.0/24", // IETF Protocol assignments + "192.0.2.0/24", // TEST-NET-1 + "192.88.99.0/24", // 6to4 Relay anycast + "192.168.0.0/16", // Private-use networks + "198.18.0.0/15", // Network interconnect + "198.51.100.0/24", // TEST-NET-2 + "203.0.113.0/24", // TEST-NET-3 + "255.255.255.255/32", // Limited broadcast + + // https://datatracker.ietf.org/doc/html/rfc1918: + "10.0.0.0/8", // Private-use networks + + // https://datatracker.ietf.org/doc/html/rfc6890: + "::1/128", // Loopback + "FC00::/7", // Unique local address + "FE80::/10", // Multicast address + } + for _, raw := range rawCIDRs { + _, cidr, err := net.ParseCIDR(raw) + if err != nil { + panic(fmt.Sprintf("parse CIDR %q: %v", raw, err)) + } + localCIDRs = append(localCIDRs, cidr) + } +} + +// IsLocalHostname returns true if given hostname is a known local address. +func IsLocalHostname(hostname string) bool { + ips, err := net.LookupIP(hostname) + if err != nil { + return true + } + for _, ip := range ips { + for _, cidr := range localCIDRs { + if cidr.Contains(ip) { + return true + } + } + } + return false +} diff --git a/internal/netutil/netutil_test.go b/internal/netutil/netutil_test.go new file mode 100644 index 00000000000..47be4e74b4d --- /dev/null +++ b/internal/netutil/netutil_test.go @@ -0,0 +1,36 @@ +// Copyright 2022 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package netutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIsLocalHostname(t *testing.T) { + tests := []struct { + hostname string + want bool + }{ + {hostname: "localhost", want: true}, + {hostname: "127.0.0.1", want: true}, + {hostname: "::1", want: true}, + {hostname: "0:0:0:0:0:0:0:1", want: true}, + {hostname: "fuf.me", want: true}, + {hostname: "127.0.0.95", want: true}, + {hostname: "0.0.0.0", want: true}, + {hostname: "192.168.123.45", want: true}, + + {hostname: "gogs.io", want: false}, + {hostname: "google.com", want: false}, + {hostname: "165.232.140.255", want: false}, + } + for _, test := range tests { + t.Run("", func(t *testing.T) { + assert.Equal(t, test.want, IsLocalHostname(test.hostname)) + }) + } +} diff --git a/internal/route/repo/webhook.go b/internal/route/repo/webhook.go index 246b0375f14..77696bbcd09 100644 --- a/internal/route/repo/webhook.go +++ b/internal/route/repo/webhook.go @@ -6,7 +6,6 @@ package repo import ( "fmt" - "net" "net/http" "net/url" "strings" @@ -21,6 +20,7 @@ import ( "gogs.io/gogs/internal/db" "gogs.io/gogs/internal/db/errors" "gogs.io/gogs/internal/form" + "gogs.io/gogs/internal/netutil" ) const ( @@ -119,60 +119,6 @@ func WebhooksNew(c *context.Context, orCtx *orgRepoContext) { c.Success(orCtx.TmplNew) } -var localCIDRs []*net.IPNet - -func init() { - // Parsing hardcoded CIDR strings should never fail, if in case it does, let's - // fail it at start. - rawCIDRs := []string{ - // https://datatracker.ietf.org/doc/html/rfc5735: - "127.0.0.0/8", // Loopback - "0.0.0.0/8", // "This" network - "100.64.0.0/10", // Shared address space - "169.254.0.0/16", // Link local - "172.16.0.0/12", // Private-use networks - "192.0.0.0/24", // IETF Protocol assignments - "192.0.2.0/24", // TEST-NET-1 - "192.88.99.0/24", // 6to4 Relay anycast - "192.168.0.0/16", // Private-use networks - "198.18.0.0/15", // Network interconnect - "198.51.100.0/24", // TEST-NET-2 - "203.0.113.0/24", // TEST-NET-3 - "255.255.255.255/32", // Limited broadcast - - // https://datatracker.ietf.org/doc/html/rfc1918: - "10.0.0.0/8", // Private-use networks - - // https://datatracker.ietf.org/doc/html/rfc6890: - "::1/128", // Loopback - "FC00::/7", // Unique local address - "FE80::/10", // Multicast address - } - for _, raw := range rawCIDRs { - _, cidr, err := net.ParseCIDR(raw) - if err != nil { - panic(fmt.Sprintf("parse CIDR %q: %v", raw, err)) - } - localCIDRs = append(localCIDRs, cidr) - } -} - -// IsLocalHostname returns true if given hostname is a known local address. -func IsLocalHostname(hostname string) bool { - ips, err := net.LookupIP(hostname) - if err != nil { - return true - } - for _, ip := range ips { - for _, cidr := range localCIDRs { - if cidr.Contains(ip) { - return true - } - } - } - return false -} - func validateWebhook(actor *db.User, l macaron.Locale, w *db.Webhook) (field, msg string, ok bool) { if !actor.IsAdmin { // 🚨 SECURITY: Local addresses must not be allowed by non-admins to prevent SSRF, @@ -182,7 +128,7 @@ func validateWebhook(actor *db.User, l macaron.Locale, w *db.Webhook) (field, ms return "PayloadURL", l.Tr("repo.settings.webhook.err_cannot_parse_payload_url", err), false } - if IsLocalHostname(payloadURL.Hostname()) { + if netutil.IsLocalHostname(payloadURL.Hostname()) { return "PayloadURL", l.Tr("repo.settings.webhook.err_cannot_use_local_addresses"), false } } diff --git a/internal/route/repo/webhook_test.go b/internal/route/repo/webhook_test.go index 30886e988d4..d10a6fcc0c9 100644 --- a/internal/route/repo/webhook_test.go +++ b/internal/route/repo/webhook_test.go @@ -13,31 +13,6 @@ import ( "gogs.io/gogs/internal/mocks" ) -func TestIsLocalHostname(t *testing.T) { - tests := []struct { - hostname string - want bool - }{ - {hostname: "localhost", want: true}, - {hostname: "127.0.0.1", want: true}, - {hostname: "::1", want: true}, - {hostname: "0:0:0:0:0:0:0:1", want: true}, - {hostname: "fuf.me", want: true}, - {hostname: "127.0.0.95", want: true}, - {hostname: "0.0.0.0", want: true}, - {hostname: "192.168.123.45", want: true}, - - {hostname: "gogs.io", want: false}, - {hostname: "google.com", want: false}, - {hostname: "165.232.140.255", want: false}, - } - for _, test := range tests { - t.Run("", func(t *testing.T) { - assert.Equal(t, test.want, IsLocalHostname(test.hostname)) - }) - } -} - func Test_validateWebhook(t *testing.T) { l := &mocks.Locale{ MockLang: "en", From f8d9a745f02388e27536a3683184373b20b200d3 Mon Sep 17 00:00:00 2001 From: Joe Chen Date: Tue, 8 Mar 2022 11:21:05 +0800 Subject: [PATCH 09/10] Check local hostname in repository migration --- internal/form/repo.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internal/form/repo.go b/internal/form/repo.go index ed9633072fc..bc0dc4269d1 100644 --- a/internal/form/repo.go +++ b/internal/form/repo.go @@ -13,6 +13,7 @@ import ( "gopkg.in/macaron.v1" "gogs.io/gogs/internal/db" + "gogs.io/gogs/internal/netutil" ) // _______________________________________ _________.______________________ _______________.___. @@ -69,6 +70,11 @@ func (f MigrateRepo) ParseRemoteAddr(user *db.User) (string, error) { if err != nil { return "", db.ErrInvalidCloneAddr{IsURLError: true} } + + if netutil.IsLocalHostname(u.Hostname()) { + return "", db.ErrInvalidCloneAddr{IsURLError: true} + } + if len(f.AuthUsername)+len(f.AuthPassword) > 0 { u.User = url.UserPassword(f.AuthUsername, f.AuthPassword) } From f04251659e5eeb03d1b4f8d2e26022cac600d370 Mon Sep 17 00:00:00 2001 From: Joe Chen Date: Tue, 8 Mar 2022 11:23:40 +0800 Subject: [PATCH 10/10] CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbb9eff35c2..1a1a4def746 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ All notable changes to Gogs are documented in this file. ### Fixed +- _Security:_ Potential SSRF in repository migration. [#6754](https://github.com/gogs/gogs/issues/6754) - Unable to use LDAP authentication on ARM machines. [#6761](https://github.com/gogs/gogs/issues/6761) ### Removed pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy