mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-18 06:24:24 +01:00
Inject HtmlSanitizer in AddBTCPayServer, remove AppHelpers deps when possible
This commit is contained in:
@@ -91,7 +91,7 @@ namespace BTCPayServer.Controllers
|
|||||||
[Route("{appId}/settings/crowdfund")]
|
[Route("{appId}/settings/crowdfund")]
|
||||||
public async Task<IActionResult> UpdateCrowdfund(string appId, UpdateCrowdfundViewModel vm)
|
public async Task<IActionResult> UpdateCrowdfund(string appId, UpdateCrowdfundViewModel vm)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty( vm.TargetCurrency) && _AppsHelper.GetCurrencyData(vm.TargetCurrency, false) == null)
|
if (!string.IsNullOrEmpty( vm.TargetCurrency) && _currencies.GetCurrencyData(vm.TargetCurrency, false) == null)
|
||||||
ModelState.AddModelError(nameof(vm.TargetCurrency), "Invalid currency");
|
ModelState.AddModelError(nameof(vm.TargetCurrency), "Invalid currency");
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -135,7 +135,7 @@ namespace BTCPayServer.Controllers
|
|||||||
EnforceTargetAmount = vm.EnforceTargetAmount,
|
EnforceTargetAmount = vm.EnforceTargetAmount,
|
||||||
StartDate = vm.StartDate,
|
StartDate = vm.StartDate,
|
||||||
TargetCurrency = vm.TargetCurrency,
|
TargetCurrency = vm.TargetCurrency,
|
||||||
Description = _AppsHelper.Sanitize( vm.Description),
|
Description = _htmlSanitizer.Sanitize( vm.Description),
|
||||||
EndDate = vm.EndDate,
|
EndDate = vm.EndDate,
|
||||||
TargetAmount = vm.TargetAmount,
|
TargetAmount = vm.TargetAmount,
|
||||||
CustomCSSLink = vm.CustomCSSLink,
|
CustomCSSLink = vm.CustomCSSLink,
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ namespace BTCPayServer.Controllers
|
|||||||
[Route("{appId}/settings/pos")]
|
[Route("{appId}/settings/pos")]
|
||||||
public async Task<IActionResult> UpdatePointOfSale(string appId, UpdatePointOfSaleViewModel vm)
|
public async Task<IActionResult> UpdatePointOfSale(string appId, UpdatePointOfSaleViewModel vm)
|
||||||
{
|
{
|
||||||
if (_AppsHelper.GetCurrencyData(vm.Currency, false) == null)
|
if (_currencies.GetCurrencyData(vm.Currency, false) == null)
|
||||||
ModelState.AddModelError(nameof(vm.Currency), "Invalid currency");
|
ModelState.AddModelError(nameof(vm.Currency), "Invalid currency");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ using BTCPayServer.Models;
|
|||||||
using BTCPayServer.Models.AppViewModels;
|
using BTCPayServer.Models.AppViewModels;
|
||||||
using BTCPayServer.Security;
|
using BTCPayServer.Security;
|
||||||
using BTCPayServer.Services.Apps;
|
using BTCPayServer.Services.Apps;
|
||||||
|
using BTCPayServer.Services.Rates;
|
||||||
|
using Ganss.XSS;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@@ -26,12 +28,16 @@ namespace BTCPayServer.Controllers
|
|||||||
ApplicationDbContextFactory contextFactory,
|
ApplicationDbContextFactory contextFactory,
|
||||||
EventAggregator eventAggregator,
|
EventAggregator eventAggregator,
|
||||||
BTCPayNetworkProvider networkProvider,
|
BTCPayNetworkProvider networkProvider,
|
||||||
|
CurrencyNameTable currencies,
|
||||||
|
HtmlSanitizer htmlSanitizer,
|
||||||
AppsHelper appsHelper)
|
AppsHelper appsHelper)
|
||||||
{
|
{
|
||||||
_UserManager = userManager;
|
_UserManager = userManager;
|
||||||
_ContextFactory = contextFactory;
|
_ContextFactory = contextFactory;
|
||||||
_EventAggregator = eventAggregator;
|
_EventAggregator = eventAggregator;
|
||||||
_NetworkProvider = networkProvider;
|
_NetworkProvider = networkProvider;
|
||||||
|
_currencies = currencies;
|
||||||
|
_htmlSanitizer = htmlSanitizer;
|
||||||
_AppsHelper = appsHelper;
|
_AppsHelper = appsHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +45,8 @@ namespace BTCPayServer.Controllers
|
|||||||
private ApplicationDbContextFactory _ContextFactory;
|
private ApplicationDbContextFactory _ContextFactory;
|
||||||
private readonly EventAggregator _EventAggregator;
|
private readonly EventAggregator _EventAggregator;
|
||||||
private BTCPayNetworkProvider _NetworkProvider;
|
private BTCPayNetworkProvider _NetworkProvider;
|
||||||
|
private readonly CurrencyNameTable _currencies;
|
||||||
|
private readonly HtmlSanitizer _htmlSanitizer;
|
||||||
private AppsHelper _AppsHelper;
|
private AppsHelper _AppsHelper;
|
||||||
|
|
||||||
[TempData]
|
[TempData]
|
||||||
|
|||||||
@@ -286,65 +286,18 @@ namespace BTCPayServer.Controllers
|
|||||||
public class AppsHelper
|
public class AppsHelper
|
||||||
{
|
{
|
||||||
ApplicationDbContextFactory _ContextFactory;
|
ApplicationDbContextFactory _ContextFactory;
|
||||||
CurrencyNameTable _Currencies;
|
private CurrencyNameTable _Currencies;
|
||||||
private HtmlSanitizer _HtmlSanitizer;
|
private readonly RateFetcher _RateFetcher;
|
||||||
|
private readonly HtmlSanitizer _HtmlSanitizer;
|
||||||
public CurrencyNameTable Currencies => _Currencies;
|
public CurrencyNameTable Currencies => _Currencies;
|
||||||
public AppsHelper(ApplicationDbContextFactory contextFactory, CurrencyNameTable currencies)
|
public AppsHelper(ApplicationDbContextFactory contextFactory, CurrencyNameTable currencies, RateFetcher rateFetcher, HtmlSanitizer htmlSanitizer)
|
||||||
{
|
{
|
||||||
_ContextFactory = contextFactory;
|
_ContextFactory = contextFactory;
|
||||||
_Currencies = currencies;
|
_Currencies = currencies;
|
||||||
ConfigureSanitizer();
|
_RateFetcher = rateFetcher;
|
||||||
}
|
_HtmlSanitizer = htmlSanitizer;
|
||||||
|
|
||||||
private void ConfigureSanitizer()
|
|
||||||
{
|
|
||||||
|
|
||||||
_HtmlSanitizer = new HtmlSanitizer();
|
|
||||||
|
|
||||||
|
|
||||||
_HtmlSanitizer.RemovingAtRule += (sender, args) =>
|
|
||||||
{
|
|
||||||
Debug.WriteLine("");
|
|
||||||
|
|
||||||
};
|
|
||||||
_HtmlSanitizer.RemovingTag += (sender, args) =>
|
|
||||||
{
|
|
||||||
Debug.WriteLine("");
|
|
||||||
if (args.Tag.TagName.Equals("img", StringComparison.InvariantCultureIgnoreCase))
|
|
||||||
{
|
|
||||||
if (!args.Tag.ClassList.Contains("img-fluid"))
|
|
||||||
{
|
|
||||||
args.Tag.ClassList.Add("img-fluid");
|
|
||||||
}
|
|
||||||
|
|
||||||
args.Cancel = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
_HtmlSanitizer.RemovingAttribute += (sender, args) =>
|
|
||||||
{
|
|
||||||
if (args.Tag.TagName.Equals("img",StringComparison.InvariantCultureIgnoreCase) &&
|
|
||||||
args.Attribute.Name.Equals( "src", StringComparison.InvariantCultureIgnoreCase) &&
|
|
||||||
args.Reason == RemoveReason.NotAllowedUrlValue)
|
|
||||||
{
|
|
||||||
args.Cancel = true;
|
|
||||||
}
|
|
||||||
Debug.WriteLine("");
|
|
||||||
|
|
||||||
};
|
|
||||||
_HtmlSanitizer.RemovingStyle += (sender, args) => { args.Cancel = true; };
|
|
||||||
_HtmlSanitizer.AllowedAttributes.Add("class");
|
|
||||||
_HtmlSanitizer.AllowedTags.Add("iframe");
|
|
||||||
_HtmlSanitizer.AllowedTags.Remove("img");
|
|
||||||
_HtmlSanitizer.AllowedAttributes.Add("webkitallowfullscreen");
|
|
||||||
_HtmlSanitizer.AllowedAttributes.Add("allowfullscreen");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Sanitize(string raw)
|
|
||||||
{
|
|
||||||
return _HtmlSanitizer.Sanitize(raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<StoreData[]> GetOwnedStores(string userId)
|
public async Task<StoreData[]> GetOwnedStores(string userId)
|
||||||
{
|
{
|
||||||
using (var ctx = _ContextFactory.CreateContext())
|
using (var ctx = _ContextFactory.CreateContext())
|
||||||
@@ -427,15 +380,15 @@ namespace BTCPayServer.Controllers
|
|||||||
.Where(kv => kv.Value != null)
|
.Where(kv => kv.Value != null)
|
||||||
.Select(c => new ViewPointOfSaleViewModel.Item()
|
.Select(c => new ViewPointOfSaleViewModel.Item()
|
||||||
{
|
{
|
||||||
Description = Sanitize(c.GetDetailString("description")),
|
Description = _HtmlSanitizer.Sanitize(c.GetDetailString("description")),
|
||||||
Id = c.Key,
|
Id = c.Key,
|
||||||
Image = Sanitize(c.GetDetailString("image")),
|
Image = _HtmlSanitizer.Sanitize(c.GetDetailString("image")),
|
||||||
Title = Sanitize(c.GetDetailString("title") ?? c.Key),
|
Title = _HtmlSanitizer.Sanitize(c.GetDetailString("title") ?? c.Key),
|
||||||
Price = c.GetDetail("price")
|
Price = c.GetDetail("price")
|
||||||
.Select(cc => new ViewPointOfSaleViewModel.Item.ItemPrice()
|
.Select(cc => new ViewPointOfSaleViewModel.Item.ItemPrice()
|
||||||
{
|
{
|
||||||
Value = decimal.Parse(cc.Value.Value, CultureInfo.InvariantCulture),
|
Value = decimal.Parse(cc.Value.Value, CultureInfo.InvariantCulture),
|
||||||
Formatted = FormatCurrency(cc.Value.Value, currency)
|
Formatted = Currencies.FormatCurrency(cc.Value.Value, currency)
|
||||||
}).Single(),
|
}).Single(),
|
||||||
Custom = c.GetDetailString("custom") == "true"
|
Custom = c.GetDetailString("custom") == "true"
|
||||||
})
|
})
|
||||||
@@ -468,15 +421,6 @@ namespace BTCPayServer.Controllers
|
|||||||
public YamlScalarNode Value { get; set; }
|
public YamlScalarNode Value { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public string FormatCurrency(string price, string currency)
|
|
||||||
{
|
|
||||||
return decimal.Parse(price, CultureInfo.InvariantCulture).ToString("C", _Currencies.GetCurrencyProvider(currency));
|
|
||||||
}
|
|
||||||
|
|
||||||
public CurrencyData GetCurrencyData(string currency, bool useFallback)
|
|
||||||
{
|
|
||||||
return _Currencies.GetCurrencyData(currency, useFallback);
|
|
||||||
}
|
|
||||||
public async Task<AppData> GetAppDataIfOwner(string userId, string appId, AppType? type = null)
|
public async Task<AppData> GetAppDataIfOwner(string userId, string appId, AppType? type = null)
|
||||||
{
|
{
|
||||||
if (userId == null || appId == null)
|
if (userId == null || appId == null)
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ namespace BTCPayServer.Crowdfund
|
|||||||
private readonly RateFetcher _RateFetcher;
|
private readonly RateFetcher _RateFetcher;
|
||||||
private readonly BTCPayNetworkProvider _BtcPayNetworkProvider;
|
private readonly BTCPayNetworkProvider _BtcPayNetworkProvider;
|
||||||
private readonly InvoiceRepository _InvoiceRepository;
|
private readonly InvoiceRepository _InvoiceRepository;
|
||||||
|
private readonly CurrencyNameTable _currencies;
|
||||||
private readonly ILogger<CrowdfundHubStreamer> _Logger;
|
private readonly ILogger<CrowdfundHubStreamer> _Logger;
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<string,(string appId, bool useAllStoreInvoices,bool useInvoiceAmount)> _QuickAppInvoiceLookup =
|
private readonly ConcurrentDictionary<string,(string appId, bool useAllStoreInvoices,bool useInvoiceAmount)> _QuickAppInvoiceLookup =
|
||||||
@@ -44,6 +45,7 @@ namespace BTCPayServer.Crowdfund
|
|||||||
RateFetcher rateFetcher,
|
RateFetcher rateFetcher,
|
||||||
BTCPayNetworkProvider btcPayNetworkProvider,
|
BTCPayNetworkProvider btcPayNetworkProvider,
|
||||||
InvoiceRepository invoiceRepository,
|
InvoiceRepository invoiceRepository,
|
||||||
|
CurrencyNameTable currencies,
|
||||||
ILogger<CrowdfundHubStreamer> logger)
|
ILogger<CrowdfundHubStreamer> logger)
|
||||||
{
|
{
|
||||||
_EventAggregator = eventAggregator;
|
_EventAggregator = eventAggregator;
|
||||||
@@ -53,6 +55,7 @@ namespace BTCPayServer.Crowdfund
|
|||||||
_RateFetcher = rateFetcher;
|
_RateFetcher = rateFetcher;
|
||||||
_BtcPayNetworkProvider = btcPayNetworkProvider;
|
_BtcPayNetworkProvider = btcPayNetworkProvider;
|
||||||
_InvoiceRepository = invoiceRepository;
|
_InvoiceRepository = invoiceRepository;
|
||||||
|
_currencies = currencies;
|
||||||
_Logger = logger;
|
_Logger = logger;
|
||||||
#pragma warning disable 4014
|
#pragma warning disable 4014
|
||||||
InitLookup();
|
InitLookup();
|
||||||
@@ -332,7 +335,7 @@ namespace BTCPayServer.Crowdfund
|
|||||||
DisplayPerksRanking = settings.DisplayPerksRanking,
|
DisplayPerksRanking = settings.DisplayPerksRanking,
|
||||||
PerkCount = perkCount,
|
PerkCount = perkCount,
|
||||||
ResetEvery = Enum.GetName(typeof(CrowdfundResetEvery),settings.ResetEvery),
|
ResetEvery = Enum.GetName(typeof(CrowdfundResetEvery),settings.ResetEvery),
|
||||||
CurrencyData = _AppsHelper.GetCurrencyData(settings.TargetCurrency, true),
|
CurrencyData = _currencies.GetCurrencyData(settings.TargetCurrency, true),
|
||||||
Info = new ViewCrowdfundViewModel.CrowdfundInfo()
|
Info = new ViewCrowdfundViewModel.CrowdfundInfo()
|
||||||
{
|
{
|
||||||
TotalContributors = invoices.Length,
|
TotalContributors = invoices.Length,
|
||||||
|
|||||||
@@ -108,6 +108,45 @@ namespace BTCPayServer.Hosting
|
|||||||
});
|
});
|
||||||
|
|
||||||
services.TryAddSingleton<AppsHelper>();
|
services.TryAddSingleton<AppsHelper>();
|
||||||
|
services.TryAddSingleton<Ganss.XSS.HtmlSanitizer>(o =>
|
||||||
|
{
|
||||||
|
|
||||||
|
var htmlSanitizer = new Ganss.XSS.HtmlSanitizer();
|
||||||
|
|
||||||
|
|
||||||
|
htmlSanitizer.RemovingAtRule += (sender, args) =>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
htmlSanitizer.RemovingTag += (sender, args) =>
|
||||||
|
{
|
||||||
|
if (args.Tag.TagName.Equals("img", StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
if (!args.Tag.ClassList.Contains("img-fluid"))
|
||||||
|
{
|
||||||
|
args.Tag.ClassList.Add("img-fluid");
|
||||||
|
}
|
||||||
|
|
||||||
|
args.Cancel = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
htmlSanitizer.RemovingAttribute += (sender, args) =>
|
||||||
|
{
|
||||||
|
if (args.Tag.TagName.Equals("img", StringComparison.InvariantCultureIgnoreCase) &&
|
||||||
|
args.Attribute.Name.Equals("src", StringComparison.InvariantCultureIgnoreCase) &&
|
||||||
|
args.Reason == Ganss.XSS.RemoveReason.NotAllowedUrlValue)
|
||||||
|
{
|
||||||
|
args.Cancel = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
htmlSanitizer.RemovingStyle += (sender, args) => { args.Cancel = true; };
|
||||||
|
htmlSanitizer.AllowedAttributes.Add("class");
|
||||||
|
htmlSanitizer.AllowedTags.Add("iframe");
|
||||||
|
htmlSanitizer.AllowedTags.Remove("img");
|
||||||
|
htmlSanitizer.AllowedAttributes.Add("webkitallowfullscreen");
|
||||||
|
htmlSanitizer.AllowedAttributes.Add("allowfullscreen");
|
||||||
|
return htmlSanitizer;
|
||||||
|
});
|
||||||
|
|
||||||
services.TryAddSingleton<LightningConfigurationProvider>();
|
services.TryAddSingleton<LightningConfigurationProvider>();
|
||||||
services.TryAddSingleton<LanguageService>();
|
services.TryAddSingleton<LanguageService>();
|
||||||
|
|||||||
@@ -42,6 +42,15 @@ namespace BTCPayServer.Services.Rates
|
|||||||
|
|
||||||
static Dictionary<string, IFormatProvider> _CurrencyProviders = new Dictionary<string, IFormatProvider>();
|
static Dictionary<string, IFormatProvider> _CurrencyProviders = new Dictionary<string, IFormatProvider>();
|
||||||
|
|
||||||
|
public string FormatCurrency(string price, string currency)
|
||||||
|
{
|
||||||
|
return FormatCurrency(decimal.Parse(price, CultureInfo.InvariantCulture), currency);
|
||||||
|
}
|
||||||
|
public string FormatCurrency(decimal price, string currency)
|
||||||
|
{
|
||||||
|
return price.ToString("C", GetCurrencyProvider(currency));
|
||||||
|
}
|
||||||
|
|
||||||
public NumberFormatInfo GetNumberFormatInfo(string currency, bool useFallback)
|
public NumberFormatInfo GetNumberFormatInfo(string currency, bool useFallback)
|
||||||
{
|
{
|
||||||
var data = GetCurrencyProvider(currency);
|
var data = GetCurrencyProvider(currency);
|
||||||
|
|||||||
Reference in New Issue
Block a user