diff --git a/BTCPayServer/Configuration/SparkConnectionString.cs b/BTCPayServer/Configuration/SparkConnectionString.cs index c93092408..2d1a13639 100644 --- a/BTCPayServer/Configuration/SparkConnectionString.cs +++ b/BTCPayServer/Configuration/SparkConnectionString.cs @@ -29,17 +29,12 @@ namespace BTCPayServer.Configuration error = "Duplicated server attribute"; return false; } - if (!Uri.IsWellFormedUriString(kv[1], UriKind.Absolute)) + if (!Uri.IsWellFormedUriString(kv[1], UriKind.RelativeOrAbsolute)) { error = "Invalid URI"; return false; } - resultTemp.Server = new Uri(kv[1], UriKind.Absolute); - if(resultTemp.Server.Scheme == "http") - { - error = "Insecure transport protocol (http)"; - return false; - } + resultTemp.Server = new Uri(kv[1], UriKind.RelativeOrAbsolute); break; case "cookiefile": case "cookiefilepath": diff --git a/BTCPayServer/Controllers/ServerController.cs b/BTCPayServer/Controllers/ServerController.cs index 2e90a65d9..73e56e483 100644 --- a/BTCPayServer/Controllers/ServerController.cs +++ b/BTCPayServer/Controllers/ServerController.cs @@ -586,7 +586,19 @@ namespace BTCPayServer.Controllers vm.WalletName = walletName; try { - vm.ServiceLink = $"{external.ConnectionString.Server.AbsoluteUri}?access-key={await external.ExtractAccessKey()}"; + string serviceUri = null; + + if (external.ConnectionString.Server.IsAbsoluteUri) + { + serviceUri = external.ConnectionString.Server.AbsoluteUri; + AssertSecure(serviceUri); + } + else + { + AssertSecure(this.Request.GetCurrentUrl()); + serviceUri = this.Request.GetRelativePathOrAbsolute(external.ConnectionString.Server.ToString()); + } + vm.ServiceLink = $"{serviceUri}?access-key={await external.ExtractAccessKey()}"; } catch (Exception ex) { @@ -596,6 +608,17 @@ namespace BTCPayServer.Controllers return View("LightningWalletServices", vm); } + private void AssertSecure(string serviceUri) + { + if (!Uri.TryCreate(serviceUri, UriKind.Absolute, out var uri)) + throw new System.Security.SecurityException("Invalid serviceUri"); + if(!uri.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase) && + !uri.DnsSafeHost.EndsWith(".onion", StringComparison.OrdinalIgnoreCase)) + { + throw new System.Security.SecurityException("You can only access this service through https or Tor"); + } + } + [Route("server/services/lnd/{cryptoCode}/{index}")] public async Task LndServices(string cryptoCode, int index, uint? nonce) {