diff --git a/config/config.go b/config/config.go index e5b43a29..5b15e059 100644 --- a/config/config.go +++ b/config/config.go @@ -10,6 +10,7 @@ import ( "path/filepath" "runtime" "strings" + "sync" ) //go:embed version @@ -57,6 +58,13 @@ func IsDebug() bool { return os.Getenv("XUI_DEBUG") == "true" } +// AllowPrivateIPs returns true if user bypasses security checks via the ALLOW_PRIVATES environment variable. +var AllowPrivateIPs = sync.OnceValue(allowPrivateIPs) + +func allowPrivateIPs() bool { + return os.Getenv("ALLOW_PRIVATE_IPS") == "true" +} + // GetBinFolderPath returns the path to the binary folder, defaulting to "bin" if not set via XUI_BIN_FOLDER. func GetBinFolderPath() string { binFolderPath := os.Getenv("XUI_BIN_FOLDER") diff --git a/web/controller/xray_setting.go b/web/controller/xray_setting.go index 396e0a6a..04117aac 100644 --- a/web/controller/xray_setting.go +++ b/web/controller/xray_setting.go @@ -3,6 +3,7 @@ package controller import ( "encoding/json" + "github.com/mhsanaei/3x-ui/v3/config" "github.com/mhsanaei/3x-ui/v3/util/common" "github.com/mhsanaei/3x-ui/v3/web/service" @@ -213,7 +214,7 @@ func (a *XraySettingController) testOutbound(c *gin.Context) { // Load the test URL from server settings to prevent SSRF via user-controlled URLs testURL, _ := a.SettingService.GetXrayOutboundTestUrl() - testURL, err := service.SanitizePublicHTTPURL(testURL, false) + testURL, err := service.SanitizePublicHTTPURL(testURL, config.AllowPrivateIPs()) if err != nil { jsonMsg(c, I18nWeb(c, "somethingWentWrong"), err) return diff --git a/web/job/xray_traffic_job.go b/web/job/xray_traffic_job.go index 7a471b4c..f58f89e5 100644 --- a/web/job/xray_traffic_job.go +++ b/web/job/xray_traffic_job.go @@ -3,6 +3,7 @@ package job import ( "encoding/json" + "github.com/mhsanaei/3x-ui/v3/config" "github.com/mhsanaei/3x-ui/v3/logger" "github.com/mhsanaei/3x-ui/v3/web/service" "github.com/mhsanaei/3x-ui/v3/web/websocket" @@ -137,7 +138,7 @@ func (j *XrayTrafficJob) informTrafficToExternalAPI(inboundTraffics []*xray.Traf logger.Warning("get ExternalTrafficInformURI failed:", err) return } - informURL, err = service.SanitizePublicHTTPURL(informURL, false) + informURL, err = service.SanitizePublicHTTPURL(informURL, config.AllowPrivateIPs()) if err != nil { logger.Warning("ExternalTrafficInformURI blocked:", err) return diff --git a/web/service/tgbot.go b/web/service/tgbot.go index 179c082f..4f0daf33 100644 --- a/web/service/tgbot.go +++ b/web/service/tgbot.go @@ -341,7 +341,7 @@ func (t *Tgbot) NewBot(token string, proxyUrl string, apiServerUrl string) (*tel // Validate API server URL if provided if apiServerUrl != "" { - safeURL, err := SanitizePublicHTTPURL(apiServerUrl, false) + safeURL, err := SanitizePublicHTTPURL(apiServerUrl, config.AllowPrivateIPs()) if err != nil { logger.Warningf("Invalid or blocked API server URL, using default: %v", err) apiServerUrl = ""