Bug 40538: Fix XSS in suspend hold modal

This patch fixes a XSS vulnerability in the
suspend hold modal in the staff interface.

By building our Javascript using Web APIs rather
than with strings and jQuery's html() method,
we're able to securely handle malicious payloads.

Test plan:
0. Apply the patch
1. Go to http://localhost:8081/cgi-bin/koha/reserve/request.pl?biblionumber=29
2. Add a hold for "koha" patron
3. Go to http://localhost:8081/cgi-bin/koha/circ/circulation.pl?borrowernumber=51
4. Click "Holds" tab and click "Suspend"
5. Note the modal loads properly
6. Go to http://localhost:8081/cgi-bin/koha/members/moremember.pl?borrowernumber=51
7. Click "Holds" tab and click "Suspend"
8. Note the modal loads properly

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
This commit is contained in:
David Cook 2025-07-29 04:07:37 +00:00 committed by Paul Derscheid
parent f09fe9e56c
commit 39daea4c76
No known key found for this signature in database
GPG Key ID: C25F9FD44CED595B
1 changed files with 23 additions and 10 deletions

View File

@ -373,16 +373,29 @@ $(document).ready(function () {
"</a>"
);
} else {
return (
"<a class='hold-suspend btn btn-default btn-xs' data-hold-id='" +
oObj.reserve_id +
"' data-hold-title='" +
oObj.title +
"'>" +
"<i class='fa fa-pause'></i> " +
__("Suspend") +
"</a>"
const link = document.createElement("a");
link.classList.add(
"hold-suspend",
"btn",
"btn-default",
"btn-xs"
);
link.setAttribute(
"data-hold-id",
oObj.reserve_id
);
link.setAttribute(
"data-hold-title",
oObj.title
);
link.textContent = " " + __("Suspend");
const icon = document.createElement("i");
icon.classList.add("fa", "fa-pause");
link.insertAdjacentElement(
"afterbegin",
icon
);
return link.outerHTML;
}
},
},
@ -491,7 +504,7 @@ $(document).ready(function () {
$(".hold-suspend").on("click", function () {
var hold_id = $(this).data("hold-id");
var hold_title = $(this).data("hold-title");
$("#suspend-modal-title").html(hold_title);
$("#suspend-modal-title").text(hold_title);
$("#suspend-modal-submit").data("hold-id", hold_id);
$("#suspend-modal").modal("show");
});