From ce5c51d3ba355adda03b280049eefe23107e3f28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A3=8E=E6=89=87=E6=BB=91=E7=BF=94=E7=BF=BC?= Date: Wed, 10 Sep 2025 08:25:52 +0800 Subject: [PATCH] TPROXY: Prevent TCP loopback (#5114) Fixes https://t.me/projectXray/4434526 --- app/proxyman/inbound/worker.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/app/proxyman/inbound/worker.go b/app/proxyman/inbound/worker.go index 40c8bc15..e5e3eeb1 100644 --- a/app/proxyman/inbound/worker.go +++ b/app/proxyman/inbound/worker.go @@ -2,6 +2,7 @@ package inbound import ( "context" + gonet "net" "sync" "sync/atomic" "time" @@ -76,6 +77,24 @@ func (w *tcpWorker) callback(conn stat.Connection) { case internet.SocketConfig_TProxy: dest = net.DestinationFromAddr(conn.LocalAddr()) } + // Check if try to connect to this inbound itself (can cause loopback) + var isLoopBack bool + if w.address == net.AnyIP || w.address == net.AnyIPv6 { + if dest.Port.Value() == w.port.Value() && IsLocal(dest.Address.IP()) { + isLoopBack = true + } + } else { + if w.hub.Addr().String() == dest.NetAddr() { + isLoopBack = true + } + } + if isLoopBack { + cancel() + conn.Close() + errors.LogError(ctx, errors.New("loopback connection detected")) + return + } + if dest.IsValid() { outbounds[0].Target = dest } @@ -544,3 +563,18 @@ func (w *dsWorker) Close() error { return nil } + +func IsLocal(ip net.IP) bool { + addrs, err := gonet.InterfaceAddrs() + if err != nil { + return false + } + for _, addr := range addrs { + if ipnet, ok := addr.(*gonet.IPNet); ok { + if ipnet.IP.Equal(ip) { + return true + } + } + } + return false +}