mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-17 05:54:26 +01:00
Make HtmlTags safer, properly sanitize in the view as well
This commit is contained in:
@@ -35,33 +35,35 @@ namespace BTCPayServer.Abstractions.Services
|
||||
return _htmlHelper.Raw(_jsonHelper.Serialize(model));
|
||||
}
|
||||
|
||||
public IHtmlContent Meta(string inputHtml) => _htmlHelper.Raw(RawMeta(inputHtml, out _));
|
||||
|
||||
public string RawMeta(string inputHtml, out bool isHtmlModified)
|
||||
{
|
||||
bool bHtmlModified;
|
||||
HtmlSanitizer _metaSanitizer = new HtmlSanitizer();
|
||||
HtmlSanitizer sane = new HtmlSanitizer();
|
||||
|
||||
_metaSanitizer.AllowedTags.Clear();
|
||||
_metaSanitizer.AllowedTags.Add("meta");
|
||||
sane.AllowedTags.Clear();
|
||||
sane.AllowedTags.Add("meta");
|
||||
|
||||
_metaSanitizer.AllowedAttributes.Clear();
|
||||
_metaSanitizer.AllowedAttributes.Add("name");
|
||||
_metaSanitizer.AllowedAttributes.Add("http-equiv");
|
||||
_metaSanitizer.AllowedAttributes.Add("content");
|
||||
_metaSanitizer.AllowedAttributes.Add("value");
|
||||
_metaSanitizer.AllowedAttributes.Add("property");
|
||||
sane.AllowedAttributes.Clear();
|
||||
sane.AllowedAttributes.Add("name");
|
||||
sane.AllowedAttributes.Add("http-equiv");
|
||||
sane.AllowedAttributes.Add("content");
|
||||
sane.AllowedAttributes.Add("value");
|
||||
sane.AllowedAttributes.Add("property");
|
||||
|
||||
_metaSanitizer.AllowDataAttributes = false;
|
||||
sane.AllowDataAttributes = false;
|
||||
|
||||
_metaSanitizer.RemovingTag += (sender, e) => bHtmlModified = true;
|
||||
_metaSanitizer.RemovingAtRule += (sender, e) => bHtmlModified = true;
|
||||
_metaSanitizer.RemovingAttribute += (sender, e) => bHtmlModified = true;
|
||||
_metaSanitizer.RemovingComment += (sender, e) => bHtmlModified = true;
|
||||
_metaSanitizer.RemovingCssClass += (sender, e) => bHtmlModified = true;
|
||||
_metaSanitizer.RemovingStyle += (sender, e) => bHtmlModified = true;
|
||||
sane.RemovingTag += (sender, e) => bHtmlModified = true;
|
||||
sane.RemovingAtRule += (sender, e) => bHtmlModified = true;
|
||||
sane.RemovingAttribute += (sender, e) => bHtmlModified = true;
|
||||
sane.RemovingComment += (sender, e) => bHtmlModified = true;
|
||||
sane.RemovingCssClass += (sender, e) => bHtmlModified = true;
|
||||
sane.RemovingStyle += (sender, e) => bHtmlModified = true;
|
||||
|
||||
bHtmlModified = false;
|
||||
|
||||
var sRet = _metaSanitizer.Sanitize(inputHtml);
|
||||
var sRet = sane.Sanitize(inputHtml);
|
||||
isHtmlModified = bHtmlModified;
|
||||
|
||||
return sRet;
|
||||
|
||||
@@ -6,6 +6,7 @@ using BTCPayServer.Abstractions.Constants;
|
||||
using BTCPayServer.Abstractions.Contracts;
|
||||
using BTCPayServer.Abstractions.Extensions;
|
||||
using BTCPayServer.Abstractions.Models;
|
||||
using BTCPayServer.Abstractions.Services;
|
||||
using BTCPayServer.Client;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Data;
|
||||
@@ -38,13 +39,16 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly IFileService _fileService;
|
||||
|
||||
public Safe Safe { get; }
|
||||
|
||||
public GreenfieldAppsController(
|
||||
AppService appService,
|
||||
UriResolver uriResolver,
|
||||
StoreRepository storeRepository,
|
||||
CurrencyNameTable currencies,
|
||||
IFileService fileService,
|
||||
UserManager<ApplicationUser> userManager
|
||||
UserManager<ApplicationUser> userManager,
|
||||
Safe safe
|
||||
)
|
||||
{
|
||||
_appService = appService;
|
||||
@@ -53,6 +57,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
_currencies = currencies;
|
||||
_fileService = fileService;
|
||||
_userManager = userManager;
|
||||
Safe = safe;
|
||||
}
|
||||
|
||||
[HttpPost("~/api/v1/stores/{storeId}/apps/crowdfund")]
|
||||
@@ -305,7 +310,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
var parsedSounds = ValidateStringArray(request.Sounds);
|
||||
var parsedColors = ValidateStringArray(request.AnimationColors);
|
||||
Enum.TryParse<BTCPayServer.Services.Apps.CrowdfundResetEvery>(request.ResetEvery.ToString(), true, out var resetEvery);
|
||||
|
||||
if (request.HtmlMetaTags is not null)
|
||||
request.HtmlMetaTags = Safe.RawMeta(request.HtmlMetaTags, out _);
|
||||
return new CrowdfundSettings
|
||||
{
|
||||
Title = request.Title?.Trim() ?? request.AppName,
|
||||
@@ -342,6 +348,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
private PointOfSaleSettings ToPointOfSaleSettings(PointOfSaleAppRequest request, PointOfSaleSettings settings)
|
||||
{
|
||||
Enum.TryParse<BTCPayServer.Plugins.PointOfSale.PosViewType>(request.DefaultView.ToString(), true, out var defaultView);
|
||||
if (request.HtmlMetaTags is not null)
|
||||
request.HtmlMetaTags = Safe.RawMeta(request.HtmlMetaTags, out _);
|
||||
|
||||
return new PointOfSaleSettings
|
||||
{
|
||||
|
||||
@@ -588,7 +588,7 @@ namespace BTCPayServer.Plugins.Crowdfund.Controllers
|
||||
});
|
||||
if (wasHtmlModified)
|
||||
{
|
||||
TempData[WellKnownTempData.ErrorMessage] = StringLocalizer["Only meta tags are allowed in HTML headers. Your HTML code has been cleaned up accordingly."].Value;
|
||||
TempData[WellKnownTempData.SuccessMessage] = StringLocalizer["Only meta tags are allowed in HTML headers. Your HTML code has been cleaned up accordingly."].Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -729,7 +729,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers
|
||||
await _appService.UpdateOrCreateApp(app);
|
||||
if (wasHtmlModified)
|
||||
{
|
||||
TempData[WellKnownTempData.ErrorMessage] = StringLocalizer["Only meta tags are allowed in HTML headers. Your HTML code has been cleaned up accordingly."].Value;
|
||||
TempData[WellKnownTempData.SuccessMessage] = StringLocalizer["Only meta tags are allowed in HTML headers. Your HTML code has been cleaned up accordingly."].Value;
|
||||
} else {
|
||||
TempData[WellKnownTempData.SuccessMessage] = StringLocalizer["App updated"].Value;
|
||||
}
|
||||
|
||||
@@ -35,8 +35,7 @@
|
||||
object-fit: scale-down;
|
||||
}
|
||||
</style>
|
||||
@* Html.Raw OK here since Html has been cleaned before in controller *@
|
||||
@Html.Raw(Model.HtmlMetaTags)
|
||||
@this.Safe.Meta(Model.HtmlMetaTags)
|
||||
<vc:ui-extension-point location="crowdfund-head" model="@Model"/>
|
||||
</head>
|
||||
<body class="min-vh-100 p-2">
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
@inject IWebHostEnvironment WebHostEnvironment
|
||||
@inject SettingsRepository SettingsRepository
|
||||
@inject BTCPayServerEnvironment Env
|
||||
|
||||
@model BTCPayServer.Plugins.PointOfSale.Models.ViewPointOfSaleViewModel
|
||||
@{
|
||||
ViewData["Title"] = string.IsNullOrEmpty(Model.Title) ? Model.StoreName : Model.Title;
|
||||
@@ -40,8 +41,7 @@
|
||||
<link rel="apple-touch-startup-image" href="~/img/splash.png">
|
||||
<link rel="manifest" href="@(await GetDynamicManifest(ViewData["Title"]!.ToString()))">
|
||||
<link href="~/pos/common.css" asp-append-version="true" rel="stylesheet" />
|
||||
@* Html.Raw OK here since Html has been cleaned before in controller *@
|
||||
@Html.Raw(Model.HtmlMetaTags)
|
||||
@this.Safe.Meta(Model.HtmlMetaTags)
|
||||
@await RenderSectionAsync("PageHeadContent", false)
|
||||
</head>
|
||||
<body class="min-vh-100">
|
||||
|
||||
Reference in New Issue
Block a user