mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2026-01-29 19:04:40 +01:00
Fix several HTML injections (#4545)
This commit is contained in:
@@ -13,6 +13,7 @@ using BTCPayServer.Services.Stores;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
|
||||
namespace BTCPayServer.Controllers
|
||||
{
|
||||
@@ -23,11 +24,13 @@ namespace BTCPayServer.Controllers
|
||||
public UIAppsController(
|
||||
UserManager<ApplicationUser> userManager,
|
||||
StoreRepository storeRepository,
|
||||
AppService appService)
|
||||
AppService appService,
|
||||
IHtmlHelper html)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_storeRepository = storeRepository;
|
||||
_appService = appService;
|
||||
Html = html;
|
||||
}
|
||||
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
@@ -35,6 +38,7 @@ namespace BTCPayServer.Controllers
|
||||
private readonly AppService _appService;
|
||||
|
||||
public string CreatedAppId { get; set; }
|
||||
public IHtmlHelper Html { get; }
|
||||
|
||||
public class AppUpdated
|
||||
{
|
||||
@@ -175,7 +179,7 @@ namespace BTCPayServer.Controllers
|
||||
if (app == null)
|
||||
return NotFound();
|
||||
|
||||
return View("Confirm", new ConfirmModel("Delete app", $"The app <strong>{app.Name}</strong> and its settings will be permanently deleted. Are you sure?", "Delete"));
|
||||
return View("Confirm", new ConfirmModel("Delete app", $"The app <strong>{Html.Encode(app.Name)}</strong> and its settings will be permanently deleted. Are you sure?", "Delete"));
|
||||
}
|
||||
|
||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
|
||||
|
||||
@@ -2,9 +2,11 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Abstractions.Extensions;
|
||||
using BTCPayServer.Abstractions.Models;
|
||||
using BTCPayServer.Abstractions.Services;
|
||||
using BTCPayServer.Client;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Models;
|
||||
@@ -41,7 +43,7 @@ namespace BTCPayServer.Controllers
|
||||
return View("Confirm", new ConfirmModel
|
||||
{
|
||||
Title = "Delete API key",
|
||||
Description = $"Any application using the API key <strong>{key.Label ?? key.Id}<strong> will immediately lose access.",
|
||||
Description = $"Any application using the API key <strong>{Html.Encode(key.Label ?? key.Id)}<strong> will immediately lose access.",
|
||||
Action = "Delete",
|
||||
ActionName = nameof(DeleteAPIKeyPost)
|
||||
});
|
||||
|
||||
@@ -16,6 +16,7 @@ using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MimeKit;
|
||||
@@ -38,6 +39,7 @@ namespace BTCPayServer.Controllers
|
||||
private readonly Fido2Service _fido2Service;
|
||||
private readonly LinkGenerator _linkGenerator;
|
||||
private readonly UserLoginCodeService _userLoginCodeService;
|
||||
private readonly IHtmlHelper Html;
|
||||
private readonly UserService _userService;
|
||||
readonly StoreRepository _StoreRepository;
|
||||
|
||||
@@ -54,7 +56,8 @@ namespace BTCPayServer.Controllers
|
||||
Fido2Service fido2Service,
|
||||
LinkGenerator linkGenerator,
|
||||
UserService userService,
|
||||
UserLoginCodeService userLoginCodeService
|
||||
UserLoginCodeService userLoginCodeService,
|
||||
IHtmlHelper htmlHelper
|
||||
)
|
||||
{
|
||||
_userManager = userManager;
|
||||
@@ -68,6 +71,7 @@ namespace BTCPayServer.Controllers
|
||||
_fido2Service = fido2Service;
|
||||
_linkGenerator = linkGenerator;
|
||||
_userLoginCodeService = userLoginCodeService;
|
||||
Html = htmlHelper;
|
||||
_userService = userService;
|
||||
_StoreRepository = storeRepository;
|
||||
}
|
||||
|
||||
@@ -225,15 +225,15 @@ namespace BTCPayServer.Controllers
|
||||
{
|
||||
// return
|
||||
return View("Confirm", new ConfirmModel("Delete admin",
|
||||
$"Unable to proceed: As the user <strong>{user.Email}</strong> is the last enabled admin, it cannot be removed."));
|
||||
$"Unable to proceed: As the user <strong>{Html.Encode(user.Email)}</strong> is the last enabled admin, it cannot be removed."));
|
||||
}
|
||||
|
||||
return View("Confirm", new ConfirmModel("Delete admin",
|
||||
$"The admin <strong>{user.Email}</strong> will be permanently deleted. This action will also delete all accounts, users and data associated with the server account. Are you sure?",
|
||||
$"The admin <strong>{Html.Encode(user.Email)}</strong> will be permanently deleted. This action will also delete all accounts, users and data associated with the server account. Are you sure?",
|
||||
"Delete"));
|
||||
}
|
||||
|
||||
return View("Confirm", new ConfirmModel("Delete user", $"The user <strong>{user.Email}</strong> will be permanently deleted. Are you sure?", "Delete"));
|
||||
return View("Confirm", new ConfirmModel("Delete user", $"The user <strong>{Html.Encode(user.Email)}</strong> will be permanently deleted. Are you sure?", "Delete"));
|
||||
}
|
||||
|
||||
[HttpPost("server/users/{userId}/delete")]
|
||||
@@ -259,9 +259,9 @@ namespace BTCPayServer.Controllers
|
||||
if (!enable && await _userService.IsUserTheOnlyOneAdmin(user))
|
||||
{
|
||||
return View("Confirm", new ConfirmModel("Disable admin",
|
||||
$"Unable to proceed: As the user <strong>{user.Email}</strong> is the last enabled admin, it cannot be disabled."));
|
||||
$"Unable to proceed: As the user <strong>{Html.Encode(user.Email)}</strong> is the last enabled admin, it cannot be disabled."));
|
||||
}
|
||||
return View("Confirm", new ConfirmModel($"{(enable ? "Enable" : "Disable")} user", $"The user <strong>{user.Email}</strong> will be {(enable ? "enabled" : "disabled")}. Are you sure?", (enable ? "Enable" : "Disable")));
|
||||
return View("Confirm", new ConfirmModel($"{(enable ? "Enable" : "Disable")} user", $"The user <strong>{Html.Encode(user.Email)}</strong> will be {(enable ? "enabled" : "disabled")}. Are you sure?", (enable ? "Enable" : "Disable")));
|
||||
}
|
||||
|
||||
[HttpPost("server/users/{userId}/toggle")]
|
||||
@@ -288,7 +288,7 @@ namespace BTCPayServer.Controllers
|
||||
if (user == null)
|
||||
return NotFound();
|
||||
|
||||
return View("Confirm", new ConfirmModel("Send verification email", $"This will send a verification email to <strong>{user.Email}</strong>.", "Send"));
|
||||
return View("Confirm", new ConfirmModel("Send verification email", $"This will send a verification email to <strong>{Html.Encode(user.Email)}</strong>.", "Send"));
|
||||
}
|
||||
|
||||
[HttpPost("server/users/{userId}/verification-email")]
|
||||
|
||||
@@ -89,7 +89,8 @@ namespace BTCPayServer.Controllers
|
||||
Logs logs,
|
||||
LinkGenerator linkGenerator,
|
||||
EmailSenderFactory emailSenderFactory,
|
||||
IHostApplicationLifetime applicationLifetime
|
||||
IHostApplicationLifetime applicationLifetime,
|
||||
IHtmlHelper html
|
||||
)
|
||||
{
|
||||
_policiesSettings = policiesSettings;
|
||||
@@ -113,6 +114,7 @@ namespace BTCPayServer.Controllers
|
||||
_linkGenerator = linkGenerator;
|
||||
_emailSenderFactory = emailSenderFactory;
|
||||
ApplicationLifetime = applicationLifetime;
|
||||
Html = html;
|
||||
}
|
||||
|
||||
[Route("server/maintenance")]
|
||||
@@ -296,6 +298,7 @@ namespace BTCPayServer.Controllers
|
||||
|
||||
public IHttpClientFactory HttpClientFactory { get; }
|
||||
public IHostApplicationLifetime ApplicationLifetime { get; }
|
||||
public IHtmlHelper Html { get; }
|
||||
|
||||
[Route("server/policies")]
|
||||
public async Task<IActionResult> Policies()
|
||||
@@ -836,7 +839,7 @@ namespace BTCPayServer.Controllers
|
||||
return NotFound();
|
||||
return View("Confirm",
|
||||
new ConfirmModel("Delete dynamic DNS service",
|
||||
$"Deleting the dynamic DNS service for <strong>{hostname}</strong> means your BTCPay Server will stop updating the associated DNS record periodically.", "Delete"));
|
||||
$"Deleting the dynamic DNS service for <strong>{Html.Encode(hostname)}</strong> means your BTCPay Server will stop updating the associated DNS record periodically.", "Delete"));
|
||||
}
|
||||
|
||||
[HttpPost("server/services/dynamic-dns/{hostname}/delete")]
|
||||
|
||||
@@ -800,9 +800,9 @@ namespace BTCPayServer.Controllers
|
||||
? ""
|
||||
: " or imported it into an external wallet. If you no longer have access to your private key (recovery seed), immediately replace the wallet";
|
||||
return
|
||||
$"<p class=\"text-danger fw-bold\">Please note that this is a <strong>{walletType} wallet</strong>!</p>" +
|
||||
$"<p class=\"text-danger fw-bold\">Do not proceed if you have not backed up the wallet{additionalText}.</p>" +
|
||||
$"<p class=\"text-start mb-0\">This action will erase the current wallet data from the server. {info}</p>";
|
||||
$"<p class=\"text-danger fw-bold\">Please note that this is a <strong>{Html.Encode(walletType)} wallet</strong>!</p>" +
|
||||
$"<p class=\"text-danger fw-bold\">Do not proceed if you have not backed up the wallet{Html.Encode(additionalText)}.</p>" +
|
||||
$"<p class=\"text-start mb-0\">This action will erase the current wallet data from the server. {Html.Encode(info)}</p>";
|
||||
}
|
||||
|
||||
private string WalletReplaceWarning(bool isHotWallet)
|
||||
|
||||
@@ -65,7 +65,8 @@ namespace BTCPayServer.Controllers
|
||||
WebhookSender webhookNotificationManager,
|
||||
IDataProtectionProvider dataProtector,
|
||||
IOptions<LightningNetworkOptions> lightningNetworkOptions,
|
||||
IOptions<ExternalServicesOptions> externalServiceOptions)
|
||||
IOptions<ExternalServicesOptions> externalServiceOptions,
|
||||
IHtmlHelper html)
|
||||
{
|
||||
_RateFactory = rateFactory;
|
||||
_Repo = repo;
|
||||
@@ -89,6 +90,7 @@ namespace BTCPayServer.Controllers
|
||||
_BtcpayServerOptions = btcpayServerOptions;
|
||||
_BTCPayEnv = btcpayEnv;
|
||||
_externalServiceOptions = externalServiceOptions;
|
||||
Html = html;
|
||||
}
|
||||
|
||||
readonly BTCPayServerOptions _BtcpayServerOptions;
|
||||
@@ -113,6 +115,7 @@ namespace BTCPayServer.Controllers
|
||||
|
||||
public string? GeneratedPairingCode { get; set; }
|
||||
public WebhookSender WebhookNotificationManager { get; }
|
||||
public IHtmlHelper Html { get; }
|
||||
public LightningNetworkOptions LightningNetworkOptions { get; }
|
||||
public IDataProtector DataProtector { get; }
|
||||
|
||||
@@ -180,7 +183,7 @@ namespace BTCPayServer.Controllers
|
||||
var user = await _UserManager.FindByIdAsync(userId);
|
||||
if (user == null)
|
||||
return NotFound();
|
||||
return View("Confirm", new ConfirmModel("Remove store user", $"This action will prevent <strong>{user.Email}</strong> from accessing this store and its settings. Are you sure?", "Remove"));
|
||||
return View("Confirm", new ConfirmModel("Remove store user", $"This action will prevent <strong>{Html.Encode(user.Email)}</strong> from accessing this store and its settings. Are you sure?", "Remove"));
|
||||
}
|
||||
|
||||
[HttpPost("{storeId}/users/{userId}/delete")]
|
||||
@@ -776,7 +779,7 @@ namespace BTCPayServer.Controllers
|
||||
var token = await _TokenRepository.GetToken(tokenId);
|
||||
if (token == null || token.StoreId != CurrentStore.Id)
|
||||
return NotFound();
|
||||
return View("Confirm", new ConfirmModel("Revoke the token", $"The access token with the label <strong>{token.Label}</strong> will be revoked. Do you wish to continue?", "Revoke"));
|
||||
return View("Confirm", new ConfirmModel("Revoke the token", $"The access token with the label <strong>{Html.Encode(token.Label)}</strong> will be revoked. Do you wish to continue?", "Revoke"));
|
||||
}
|
||||
|
||||
[HttpPost("{storeId}/tokens/{tokenId}/revoke")]
|
||||
|
||||
Reference in New Issue
Block a user