Fix: If reverse proxy wasn't well configured, and error message should have been displayed (#4322)

This commit is contained in:
Nicolas Dorier
2022-11-22 03:32:19 +09:00
committed by GitHub
parent 20025f254c
commit bf597495ff
5 changed files with 35 additions and 36 deletions

View File

@@ -9,6 +9,7 @@
@using BTCPayServer.Client @using BTCPayServer.Client
@using BTCPayServer.Services @using BTCPayServer.Services
@using BTCPayServer.Views.CustodianAccounts @using BTCPayServer.Views.CustodianAccounts
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContext;
@inject BTCPayServerEnvironment Env @inject BTCPayServerEnvironment Env
@inject SignInManager<ApplicationUser> SignInManager @inject SignInManager<ApplicationUser> SignInManager
@inject PoliciesSettings PoliciesSettings @inject PoliciesSettings PoliciesSettings
@@ -227,7 +228,7 @@
})() })()
</script> </script>
} }
else if (Env.IsSecure) else if (Env.IsSecure(HttpContext.HttpContext))
{ {
<ul class="navbar-nav"> <ul class="navbar-nav">
@if (!PoliciesSettings.LockSubscription) @if (!PoliciesSettings.LockSubscription)

View File

@@ -227,7 +227,7 @@ namespace BTCPayServer.Controllers
private async Task<LoginWithFido2ViewModel> BuildFido2ViewModel(bool rememberMe, ApplicationUser user) private async Task<LoginWithFido2ViewModel> BuildFido2ViewModel(bool rememberMe, ApplicationUser user)
{ {
if (_btcPayServerEnvironment.IsSecure) if (_btcPayServerEnvironment.IsSecure(HttpContext))
{ {
var r = await _fido2Service.RequestLogin(user.Id); var r = await _fido2Service.RequestLogin(user.Id);
if (r is null) if (r is null)
@@ -247,7 +247,7 @@ namespace BTCPayServer.Controllers
private async Task<LoginWithLNURLAuthViewModel> BuildLNURLAuthViewModel(bool rememberMe, ApplicationUser user) private async Task<LoginWithLNURLAuthViewModel> BuildLNURLAuthViewModel(bool rememberMe, ApplicationUser user)
{ {
if (_btcPayServerEnvironment.IsSecure) if (_btcPayServerEnvironment.IsSecure(HttpContext))
{ {
var r = await _lnurlAuthService.RequestLogin(user.Id); var r = await _lnurlAuthService.RequestLogin(user.Id);
if (r is null) if (r is null)
@@ -777,7 +777,7 @@ namespace BTCPayServer.Controllers
private bool CanLoginOrRegister() private bool CanLoginOrRegister()
{ {
return _btcPayServerEnvironment.IsDeveloping || _btcPayServerEnvironment.IsSecure; return _btcPayServerEnvironment.IsDeveloping || _btcPayServerEnvironment.IsSecure(HttpContext);
} }
private void SetInsecureFlags() private void SetInsecureFlags()

View File

@@ -67,7 +67,7 @@ namespace BTCPayServer.Controllers
[HttpGet] [HttpGet]
public async Task<IActionResult> AddApiKey() public async Task<IActionResult> AddApiKey()
{ {
if (!_btcPayServerEnvironment.IsSecure) if (!_btcPayServerEnvironment.IsSecure(HttpContext))
{ {
TempData.SetStatusMessageModel(new StatusMessageModel() TempData.SetStatusMessageModel(new StatusMessageModel()
{ {
@@ -84,7 +84,7 @@ namespace BTCPayServer.Controllers
public async Task<IActionResult> AuthorizeAPIKey(string[] permissions, string applicationName = null, Uri redirect = null, public async Task<IActionResult> AuthorizeAPIKey(string[] permissions, string applicationName = null, Uri redirect = null,
bool strict = true, bool selectiveStores = false, string applicationIdentifier = null) bool strict = true, bool selectiveStores = false, string applicationIdentifier = null)
{ {
if (!_btcPayServerEnvironment.IsSecure) if (!_btcPayServerEnvironment.IsSecure(HttpContext))
{ {
TempData.SetStatusMessageModel(new StatusMessageModel TempData.SetStatusMessageModel(new StatusMessageModel
{ {

View File

@@ -14,11 +14,9 @@ namespace BTCPayServer.Services
{ {
public class BTCPayServerEnvironment public class BTCPayServerEnvironment
{ {
readonly IHttpContextAccessor httpContext;
readonly TorServices torServices; readonly TorServices torServices;
public BTCPayServerEnvironment(IWebHostEnvironment env, BTCPayNetworkProvider provider, IHttpContextAccessor httpContext, TorServices torServices, BTCPayServerOptions opts) public BTCPayServerEnvironment(IWebHostEnvironment env, BTCPayNetworkProvider provider, TorServices torServices, BTCPayServerOptions opts)
{ {
this.httpContext = httpContext;
Version = typeof(BTCPayServerEnvironment).GetTypeInfo().Assembly.GetCustomAttribute<AssemblyFileVersionAttribute>().Version; Version = typeof(BTCPayServerEnvironment).GetTypeInfo().Assembly.GetCustomAttribute<AssemblyFileVersionAttribute>().Version;
#if DEBUG #if DEBUG
Build = "Debug"; Build = "Debug";
@@ -41,9 +39,6 @@ namespace BTCPayServer.Services
get; set; get; set;
} }
public string ExpectedDomain => httpContext.HttpContext.Request.Host.Host;
public string ExpectedHost => httpContext.HttpContext.Request.Host.Value;
public string ExpectedProtocol => httpContext.HttpContext.Request.Scheme;
public string OnionUrl => this.torServices.Services.Where(s => s.ServiceType == TorServiceType.BTCPayServer) public string OnionUrl => this.torServices.Services.Where(s => s.ServiceType == TorServiceType.BTCPayServer)
.Select(s => $"http://{s.OnionHost}").FirstOrDefault(); .Select(s => $"http://{s.OnionHost}").FirstOrDefault();
@@ -67,19 +62,14 @@ namespace BTCPayServer.Services
} }
} }
public bool IsSecure public bool IsSecure(HttpContext httpContext)
{ {
get return NetworkType != ChainName.Mainnet ||
{ httpContext.Request.Scheme == "https" ||
return NetworkType != ChainName.Mainnet || httpContext.Request.Host.Host.EndsWith(".onion", StringComparison.OrdinalIgnoreCase) ||
httpContext.HttpContext.Request.Scheme == "https" || Extensions.IsLocalNetwork(httpContext.Request.Host.Host);
httpContext.HttpContext.Request.Host.Host.EndsWith(".onion", StringComparison.OrdinalIgnoreCase) ||
Extensions.IsLocalNetwork(httpContext.HttpContext.Request.Host.Host);
}
} }
public HttpContext Context => httpContext.HttpContext;
public override string ToString() public override string ToString()
{ {
StringBuilder txt = new StringBuilder(); StringBuilder txt = new StringBuilder();

View File

@@ -1,6 +1,7 @@
@using BTCPayServer.Abstractions.Extensions @using BTCPayServer.Abstractions.Extensions
@using BTCPayServer.Components.StoreSelector @using BTCPayServer.Components.StoreSelector
@using BTCPayServer.Components.MainNav @using BTCPayServer.Components.MainNav
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor _context;
@inject BTCPayServer.Services.BTCPayServerEnvironment _env @inject BTCPayServer.Services.BTCPayServerEnvironment _env
@inject SignInManager<ApplicationUser> _signInManager @inject SignInManager<ApplicationUser> _signInManager
@inject UserManager<ApplicationUser> _userManager @inject UserManager<ApplicationUser> _userManager
@@ -15,6 +16,8 @@
var user = await _userManager.GetUserAsync(User); var user = await _userManager.GetUserAsync(User);
notificationDisabled = user?.DisabledNotifications == "all"; notificationDisabled = user?.DisabledNotifications == "all";
} }
var expectedScheme = _context.HttpContext.Request.Scheme;
var expectedHost = _context.HttpContext.Request.Host.ToString();
} }
<!DOCTYPE html> <!DOCTYPE html>
@@ -37,21 +40,20 @@
</div> </div>
<vc:main-nav /> <vc:main-nav />
</header> </header>
<template id="badUrl">
<div class="alert alert-danger alert-dismissible m-3" role="alert">
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">
<vc:icon symbol="close"/>
</button>
<span>
BTCPay is expecting you to access this website from <strong>@(expectedScheme)://@(expectedHost)/</strong>.
If you use a reverse proxy, please set the <strong>X-Forwarded-Proto</strong> header to <strong id="browserScheme">@(expectedScheme)</strong>
(<a href="https://docs.btcpayserver.org/FAQ/Deployment/#cause-3-btcpay-is-expecting-you-to-access-this-website-from" target="_blank" class="alert-link" rel="noreferrer noopener">More information</a>)
</span>
</div>
</template>
<main id="mainContent"> <main id="mainContent">
@if (_env.Context.Request.Host.ToString() != _env.ExpectedHost || _env.Context.Request.Scheme != _env.ExpectedProtocol) @if (!_env.IsSecure(_context.HttpContext))
{
<div id="badUrl" class="alert alert-danger alert-dismissible m-3" role="alert">
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">
<vc:icon symbol="close"/>
</button>
<span>
BTCPay is expecting you to access this website from <strong>@(_env.ExpectedProtocol)://@(_env.ExpectedHost)/</strong>.
If you use a reverse proxy, please set the <strong>X-Forwarded-Proto</strong> header to <strong id="browserScheme">@(_env.ExpectedProtocol)</strong>
(<a href="https://docs.btcpayserver.org/FAQ/Deployment/#cause-3-btcpay-is-expecting-you-to-access-this-website-from" target="_blank" class="alert-link" rel="noreferrer noopener">More information</a>)
</span>
</div>
}
@if (!_env.IsSecure)
{ {
<div id="insecureEnv" class="alert alert-danger alert-dismissible" style="position:absolute; top:75px;" role="alert"> <div id="insecureEnv" class="alert alert-danger alert-dismissible" style="position:absolute; top:75px;" role="alert">
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"> <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">
@@ -76,6 +78,12 @@
@if (!notificationDisabled) @if (!notificationDisabled)
{ {
<script> <script>
var mainContent = document.getElementById("mainContent");
if (window.location.protocol != "@(expectedScheme):" || window.location.host != "@expectedHost")
{
var tmpl = document.getElementById("badUrl");
mainContent.prepend(tmpl.content.cloneNode(true));
}
if ('WebSocket' in window && window.WebSocket.CLOSING === 2) { if ('WebSocket' in window && window.WebSocket.CLOSING === 2) {
const { host, protocol } = window.location; const { host, protocol } = window.location;
var wsUri = "@_linkGenerator.GetPathByAction("SubscribeUpdates", "UINotifications", pathBase: Context.Request.PathBase)"; var wsUri = "@_linkGenerator.GetPathByAction("SubscribeUpdates", "UINotifications", pathBase: Context.Request.PathBase)";