addrIsLocalIp only treats an address as local when its port equals Config.Port:
|
func addrIsLocalIp(config *Config, addr *net.TCPAddr) bool { |
|
if addr.Port == int(config.Port) { |
When smokescreen is started with a caller-supplied listener, StartWithConfig assigns config.Listener directly and never reads listener.Addr() or updates Config.Port:
|
listener := config.Listener |
|
|
|
if listener == nil { |
|
listener, err = findListener(config.Ip, config.Port) |
Effect
If the supplied listener binds a different port than Config.Port (e.g. Config.Port 4750, listener on 4751), a CONNECT to the proxy's own address on the real listener port is not classified as a self-connection. For an allowed local range this can let the proxy dial itself, enabling recursive proxying and resource exhaustion.
Reproduction
- Build a
Config with Port=4750 and LocalIPs containing 127.0.0.1.
- Provide
Config.Listener bound to 127.0.0.1:4751 and start the proxy.
- Send CONNECT through the proxy to
127.0.0.1:4751 and compare with :4750.
Scope
Reachable via the embedded API when a custom listener binds a port other than Config.Port; the standard CLI path (which derives the listener from Config.Port) is not affected.
Suggested fix
When a listener is supplied, set Config.Port from listener.Addr() before initializing self-connection detection, or compare against the listener's actual port in addrIsLocalIp.
Found while testing Ito, an automated code-review tool, against recently-merged PRs. It's free for open source. Sharing this because it looked like a real bug worth fixing, not to sell anything: https://app.ito.ai/share/0c0a8532-eeb3-4d6a-9a6e-77b451783f5b?tab=details
addrIsLocalIponly treats an address as local when its port equalsConfig.Port:smokescreen/pkg/smokescreen/smokescreen.go
Lines 291 to 292 in f03c477
When smokescreen is started with a caller-supplied listener,
StartWithConfigassignsconfig.Listenerdirectly and never readslistener.Addr()or updatesConfig.Port:smokescreen/pkg/smokescreen/smokescreen.go
Lines 1054 to 1057 in f03c477
Effect
If the supplied listener binds a different port than
Config.Port(e.g.Config.Port4750, listener on 4751), a CONNECT to the proxy's own address on the real listener port is not classified as a self-connection. For an allowed local range this can let the proxy dial itself, enabling recursive proxying and resource exhaustion.Reproduction
ConfigwithPort=4750andLocalIPscontaining127.0.0.1.Config.Listenerbound to127.0.0.1:4751and start the proxy.127.0.0.1:4751and compare with:4750.Scope
Reachable via the embedded API when a custom listener binds a port other than
Config.Port; the standard CLI path (which derives the listener fromConfig.Port) is not affected.Suggested fix
When a listener is supplied, set
Config.Portfromlistener.Addr()before initializing self-connection detection, or compare against the listener's actual port inaddrIsLocalIp.Found while testing Ito, an automated code-review tool, against recently-merged PRs. It's free for open source. Sharing this because it looked like a real bug worth fixing, not to sell anything: https://app.ito.ai/share/0c0a8532-eeb3-4d6a-9a6e-77b451783f5b?tab=details