From 980b1af3325c4a990b08e10ffcd3f6229982f7eb Mon Sep 17 00:00:00 2001 From: Arunesh Dwivedi Date: Mon, 20 Jul 2026 06:46:49 +0000 Subject: [PATCH] fix: deny ranges take precedence over allow ranges classifyAddr checked AllowRanges before DenyRanges, so an address explicitly denied via --deny-address (or --deny-range) was still allowed when it also fell inside an --allow-range. Check DenyRanges first so a denied address is always rejected regardless of any allow range. Fixes #236 Signed-off-by: Arunesh Dwivedi --- pkg/smokescreen/smokescreen.go | 6 +++--- pkg/smokescreen/smokescreen_test.go | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/pkg/smokescreen/smokescreen.go b/pkg/smokescreen/smokescreen.go index 9be25d4a..54a69f20 100644 --- a/pkg/smokescreen/smokescreen.go +++ b/pkg/smokescreen/smokescreen.go @@ -310,10 +310,10 @@ func classifyAddr(config *Config, addr *net.TCPAddr) ipType { } } - if addrIsInRuleRange(config.AllowRanges, addr) { - return ipAllowUserConfigured - } else if addrIsInRuleRange(config.DenyRanges, addr) { + if addrIsInRuleRange(config.DenyRanges, addr) { return ipDenyUserConfigured + } else if addrIsInRuleRange(config.AllowRanges, addr) { + return ipAllowUserConfigured } else if addrHasIPv6Embedding(addr) { // Block IPv6 addresses that embed IPv4 addresses (NAT64, 6to4, Teredo, IPv4-mapped) // These can bypass IPv4 safety checks and enable SSRF attacks diff --git a/pkg/smokescreen/smokescreen_test.go b/pkg/smokescreen/smokescreen_test.go index 802b7a17..a0cf06ea 100644 --- a/pkg/smokescreen/smokescreen_test.go +++ b/pkg/smokescreen/smokescreen_test.go @@ -255,6 +255,7 @@ func TestSelectTargetAddr(t *testing.T) { temporarilyDeferredIPs []string allowRanges []string denyRanges []string + denyAddresses []string expectedIP string expectError bool errorContains string @@ -312,6 +313,23 @@ func TestSelectTargetAddr(t *testing.T) { expectedIP: "8.8.8.8", expectError: false, }, + { + name: "Deny address takes precedence over allow range", + ips: []string{"192.168.1.5", "192.168.1.6"}, + port: 80, + allowRanges: []string{"192.168.0.0/16"}, + denyAddresses: []string{"192.168.1.5"}, + expectedIP: "192.168.1.6", + expectError: false, + }, + { + name: "Deny address blocks all IPs even inside allow range", + ips: []string{"192.168.1.5"}, + port: 80, + allowRanges: []string{"192.168.0.0/16"}, + denyAddresses: []string{"192.168.1.5"}, + expectError: true, + }, { name: "Deny range forces fallback to deferred IP", ips: []string{"1.1.1.1", "8.8.8.8"}, @@ -340,6 +358,11 @@ func TestSelectTargetAddr(t *testing.T) { require.NoError(t, err) } + if len(tt.denyAddresses) > 0 { + err := config.SetDenyAddresses(tt.denyAddresses) + require.NoError(t, err) + } + config.TemporarilyDeferredIPs = tt.temporarilyDeferredIPs // Convert string IPs to net.IP