From 1045378e2393376ca1233d5859e742f48f9655d5 Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Sun, 17 May 2026 12:50:10 +0200 Subject: [PATCH] fix(xray): emit only protocol-relevant fields per client entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Xray config synthesizer was writing every identifier field (id, password, flow, auth, security/method, reverse) on every client entry regardless of the inbound's protocol. Xray ignores unknown fields, so the config worked, but it diverged from the spec and leaked secrets across protocols when one client was attached to multiple inbounds — a VLESS inbound's generated config carried the same client's Trojan password and Hysteria auth alongside its uuid. Switch on inbound.Protocol when building each entry: - VLESS / PortFallback: id, flow, reverse - VMess: id, security - Trojan: password, flow - Shadowsocks: password, method - Hysteria / Hysteria2: auth email is emitted for every protocol. Co-Authored-By: Claude Opus 4.7 --- web/service/xray.go | 53 ++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/web/service/xray.go b/web/service/xray.go index 6d9c3a70..9ca32fd9 100644 --- a/web/service/xray.go +++ b/web/service/xray.go @@ -146,23 +146,42 @@ func (s *XrayService) GetXrayConfig() (*xray.Config, error) { flow = "xtls-rprx-vision" } entry := map[string]any{"email": c.Email} - if c.ID != "" { - entry["id"] = c.ID - } - if c.Password != "" { - entry["password"] = c.Password - } - if flow != "" { - entry["flow"] = flow - } - if c.Auth != "" { - entry["auth"] = c.Auth - } - if c.Security != "" { - entry["method"] = c.Security - } - if c.Reverse != nil { - entry["reverse"] = c.Reverse + switch inbound.Protocol { + case model.VLESS, model.PortFallback: + if c.ID != "" { + entry["id"] = c.ID + } + if flow != "" { + entry["flow"] = flow + } + if c.Reverse != nil { + entry["reverse"] = c.Reverse + } + case model.VMESS: + if c.ID != "" { + entry["id"] = c.ID + } + if c.Security != "" { + entry["security"] = c.Security + } + case model.Trojan: + if c.Password != "" { + entry["password"] = c.Password + } + if flow != "" { + entry["flow"] = flow + } + case model.Shadowsocks: + if c.Password != "" { + entry["password"] = c.Password + } + if c.Security != "" { + entry["method"] = c.Security + } + case model.Hysteria, model.Hysteria2: + if c.Auth != "" { + entry["auth"] = c.Auth + } } finalClients = append(finalClients, entry) }