From 61e9b223da88ff0a3ffec39410b83d66a75d762d Mon Sep 17 00:00:00 2001 From: jasper <156617797+jasperdingg@users.noreply.github.com> Date: Sat, 31 Oct 2026 18:57:28 -0700 Subject: [PATCH] core: reject overlong ports in ParseNetworkAddress (#8277) --- listeners.go | 6 ++++++ listeners_test.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/listeners.go b/listeners.go index 445496ad4..23f6680eb 100644 --- a/listeners.go +++ b/listeners.go @@ -348,6 +348,9 @@ func ParseNetworkAddressWithDefaults(addr, defaultNetwork string, defaultPort ui start = uint64(defaultPort) end = uint64(defaultPort) } else { + if len(port) > maxPortLen { + return NetworkAddress{}, fmt.Errorf("invalid port: longer than %d characters", maxPortLen) + } before, after, found := strings.Cut(port, "-") if !found { after = before @@ -776,3 +779,6 @@ type PacketConnWrapper interface { var listenerPool = NewUsagePool() const maxPortSpan = 65535 + +// maxPortLen is the length of the longest valid port range. +const maxPortLen = len("65535-65535") diff --git a/listeners_test.go b/listeners_test.go index 589904ee5..acb0ff298 100644 --- a/listeners_test.go +++ b/listeners_test.go @@ -19,6 +19,7 @@ import ( "crypto/tls" "net" "reflect" + "strings" "testing" "github.com/caddyserver/caddy/v2/internal" @@ -343,6 +344,21 @@ func TestParseNetworkAddress(t *testing.T) { defaultNetwork: "tcp", expectErr: true, }, + { + input: "localhost:65535-65535", + defaultNetwork: "tcp", + expectAddr: NetworkAddress{ + Network: "tcp", + Host: "localhost", + StartPort: 65535, + EndPort: 65535, + }, + }, + { + input: "localhost:000000000080", + defaultNetwork: "tcp", + expectErr: true, + }, } { actualAddr, err := ParseNetworkAddressWithDefaults(tc.input, tc.defaultNetwork, tc.defaultPort) if tc.expectErr && err == nil { @@ -361,6 +377,26 @@ func TestParseNetworkAddress(t *testing.T) { } } +// A very long port should fail with a short error (issue #8229). +func TestParseNetworkAddressLongPort(t *testing.T) { + junk := strings.Repeat("\x7f", 1<<20) + for i, input := range []string{ + ":" + junk, + ":80-" + junk, + ":" + junk + "-80", + "localhost:" + strings.Repeat("9", 1<<20), + } { + _, err := ParseNetworkAddress(input) + if err == nil { + t.Errorf("Test %d: expected error but got none", i) + continue + } + if len(err.Error()) > 100 { + t.Errorf("Test %d: error message is %d bytes, expected at most 100", i, len(err.Error())) + } + } +} + func TestParseNetworkAddressWithDefaults(t *testing.T) { for i, tc := range []struct { input string