What changed, and why it matters
This commit fixes a user-interface bug where a confirmation modal dialog would not close properly. The change removes an outer wrapper div that had Bootstrap CSS classes making the modal appear statically and always visible, which prevented the normal modal close behavior. There is no direct evidence in the commit of a security vulnerability such as cross-site scripting or request forgery.
Treat as a routine UI bug fix. Review the modal behavior in affected workflows to confirm dialogs now close correctly. No security-specific action is required based on this diff alone.
Security signals we found
UI-only fix with no changes to input validation, output encoding, authorization, or antiforgery logic
Safe.Raw(Model.Description) remains present but is unchanged; no new injection surface introduced by this diff
No mention of security, CVE, researcher attribution, or exploit in commit title/message
Evidence from the diff
The patch modifies BTCPayServer/Views/Shared/ConfirmModal.cshtml by removing the outer
Changed components
BTCPayServer/Views/Shared/ConfirmModal.cshtmlInspect captured patch +51 / −52
diff --git a/BTCPayServer/Views/Shared/ConfirmModal.cshtml b/BTCPayServer/Views/Shared/ConfirmModal.cshtml
index a0cdba3..bb47797 100644
--- a/BTCPayServer/Views/Shared/ConfirmModal.cshtml
+++ b/BTCPayServer/Views/Shared/ConfirmModal.cshtml
@@ -9,70 +9,69 @@
actionUrl = linkGenerator.GetPathByAction(Model.ActionName, controllerName, values: Model.ActionValues, pathBase: Context.Request.PathBase);
}
}
-<div class="modal position-static d-block" tabindex="-1">
- <div class="modal-dialog modal-dialog-centered">
- <div class="modal-content">
- <div class="modal-header">
- <h4 class="modal-title" id="@Html.Id("ConfirmTitle")">@Model.Title</h4>
- <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="@StringLocalizer["Close"]">
- <vc:icon symbol="close" />
- </button>
- </div>
- <div class="modal-body">
- <div id="@Html.Id("ConfirmDescription")">
- @if (Model.DescriptionHtml)
- {
- @Safe.Raw(Model.Description)
- }
- else
- {
- @Model.Description
- }
- </div>
+<div class="modal-dialog modal-dialog-centered">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h4 class="modal-title" id="@Html.Id("ConfirmTitle")">@Model.Title</h4>
+ <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="@StringLocalizer["Close"]">
+ <vc:icon symbol="close" />
+ </button>
+ </div>
+
+ <div class="modal-body">
+ <div id="@Html.Id("ConfirmDescription")">
+ @if (Model.DescriptionHtml)
+ {
+ @Safe.Raw(Model.Description)
+ }
+ else
+ {
+ @Model.Description
+ }
</div>
+ </div>
- @if (!string.IsNullOrEmpty(Model.Action))
+ @if (!string.IsNullOrEmpty(Model.Action))
+ {
+ @if (Model.GenerateForm)
{
- @if (Model.GenerateForm)
+ if (Model.Antiforgery is null)
{
- if (Model.Antiforgery is null)
- {
- <form id="@Html.Id("ConfirmForm")" method="post" action="@Url.EnsureLocal(actionUrl, Context.Request)"
- rel="noreferrer noopener">
- @{ ModalContent(); }
- </form>
- }
- else
- {
- <form id="@Html.Id("ConfirmForm")" method="post" asp-antiforgery="@Model.Antiforgery" action="@Url.EnsureLocal(actionUrl, Context.Request)"
- rel="noreferrer noopener">
- @{ ModalContent(); }
- </form>
- }
+ <form id="@Html.Id("ConfirmForm")" method="post" action="@Url.EnsureLocal(actionUrl, Context.Request)"
+ rel="noreferrer noopener">
+ @{ ModalContent(); }
+ </form>
}
else
{
- ModalContent();
+ <form id="@Html.Id("ConfirmForm")" method="post" asp-antiforgery="@Model.Antiforgery" action="@Url.EnsureLocal(actionUrl, Context.Request)"
+ rel="noreferrer noopener">
+ @{ ModalContent(); }
+ </form>
}
+ }
+ else
+ {
+ ModalContent();
+ }
- @functions{
-
- void ModalContent()
- {
- <div class="modal-body pt-0" id="@Html.Id("ConfirmText")" hidden>
- <label for="@Html.Id("ConfirmInput")" class="form-label">Confirm the action by typing <strong
- id="@Html.Id("ConfirmInputText")"></strong>:</label>
- <input id="@Html.Id("ConfirmInput")" class="form-control" />
- </div>
- <div class="modal-footer">
- <button type="button" class="btn btn-secondary only-for-js" data-bs-dismiss="modal" id="@Html.Id("ConfirmCancel")">Cancel</button>
- <button type="submit" class="btn modal-confirm @Model.ButtonClass" id="@Html.Id("ConfirmContinue")">@Model.Action</button>
- </div>
- }
+ @functions{
+ void ModalContent()
+ {
+ <div class="modal-body pt-0" id="@Html.Id("ConfirmText")" hidden>
+ <label for="@Html.Id("ConfirmInput")" class="form-label">Confirm the action by typing <strong
+ id="@Html.Id("ConfirmInputText")"></strong>:</label>
+ <input id="@Html.Id("ConfirmInput")" class="form-control" />
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-secondary only-for-js" data-bs-dismiss="modal" id="@Html.Id("ConfirmCancel")">Cancel</button>
+ <button type="submit" class="btn modal-confirm @Model.ButtonClass" id="@Html.Id("ConfirmContinue")">@Model.Action</button>
+ </div>
}
+
}
- </div>
+ }
</div>
</div>
Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.