From c0ce4d57cdcd354b3f0d1f70da17909888c8ad41 Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Mon, 4 May 2026 14:15:34 +0200 Subject: [PATCH] Bug 42471: [25.05] Prevent XSS in suggestion.tt escape_str all the things Signed-off-by: David Cook Signed-off-by: Martin Renvoize Signed-off-by: Wainui Witika-Park --- .../prog/en/modules/suggestion/suggestion.tt | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/suggestion/suggestion.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/suggestion/suggestion.tt index 93d3da8c42..ab157f7424 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/suggestion/suggestion.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/suggestion/suggestion.tt @@ -1345,7 +1345,7 @@ searchable: false, orderable: false, render: function (data, type, row, meta) { - return ''.format(row.suggestion_id); + return ''.format(escape_str(row.suggestion_id)); } }, { @@ -1353,19 +1353,19 @@ searchable: true, orderable: true, render: function (data, type, row, meta) { - let node = '%s'.format(row.suggestion_id, _("suggestion"), row.title); - if(row.author) node += ', by %s'.format(row.author); + let node = '%s'.format(escape_str(row.suggestion_id), escape_str(_("suggestion")), escape_str(row.title)); + if(row.author) node += ', by %s'.format(escape_str(row.author)); node += '
'; - if(row.copyright_date) node += ' © %s'.format(row.copyright_date); - if(row.volume_desc) node += '; %s:%s'.format(_("Volume"), row.volume_desc); - if(row.isbn) node += '; %s:%s'.format(_("ISBN"), row.isbn); - if(row.publisher_code) node += '; %s %s'.format(_("Published by"), row.publisher_code); - if(row.publication_year && row.publication_year != 0) node += '; %s'.format(row.publication_year); - if(row.publication_place) node += '; %s'.format(row.publication_place); - if(row.collection_title) node += '; %s'.format(row.collection_title); - if(row.item_type && row._strings.item_type.str) node += '; %s'.format(row._strings.item_type.str); - if(row.note) node += '
%s
'.format(row.note); - if(row.archived) node += '
%s'.format(_("Archived")); + if(row.copyright_date) node += ' © %s'.format(escape_str(row.copyright_date)); + if(row.volume_desc) node += '; %s:%s'.format(escape_str(_("Volume")), escape_str(row.volume_desc)); + if(row.isbn) node += '; %s:%s'.format(escape_str(_("ISBN")), escape_str(row.isbn)); + if(row.publisher_code) node += '; %s %s'.format(escape_str(_("Published by")), escape_str(row.publisher_code)); + if(row.publication_year && row.publication_year != 0) node += '; %s'.format(escape_str(row.publication_year)); + if(row.publication_place) node += '; %s'.format(escape_str(row.publication_place)); + if(row.collection_title) node += '; %s'.format(escape_str(row.collection_title)); + if(row.item_type && row._strings.item_type.str) node += '; %s'.format(escape_str(row._strings.item_type.str)); + if(row.note) node += '
%s
'.format(escape_str(row.note)); + if(row.archived) node += '
%s'.format(escape_str(_("Archived"))); return node; } }, @@ -1376,9 +1376,9 @@ render: function (data, type, row, meta) { let suggester = row.suggester; if(suggester) { - let node = '%s'.format(suggester.patron_id, suggester.surname); - if(suggester.firstname) node += ', %s'.format(suggester.firstname); - if(suggester.cardnumber) node += ' (%s)'.format(suggester.cardnumber); + let node = '%s'.format(escape_str(suggester.patron_id), escape_str(suggester.surname)); + if(suggester.firstname) node += ', %s'.format(escape_str(suggester.firstname)); + if(suggester.cardnumber) node += ' (%s)'.format(escape_str(suggester.cardnumber)); node += ''; return node; } @@ -1415,8 +1415,8 @@ orderable: true, render: function (data, type, row, meta) { if(row.manager) { - let node = '%s'.format(row.manager?.patron_id, row.manager?.surname); - if(row.manager?.firstname) node += ', %s'.format(row.manager?.firstname); + let node = '%s'.format(escape_str(row.manager?.patron_id), escape_str(row.manager?.surname)); + if(row.manager?.firstname) node += ', %s'.format(escape_str(row.manager?.firstname)); node += ''; return node; } @@ -1436,10 +1436,10 @@ searchable: true, orderable: true, render: function (data, type, row, meta) { - if(row.last_modifier) { - let node = '%s'.format(row.last_modifier?.patron_id, row.last_modifier?.surname); - if(row.last_modifier?.firstname) node += ', %s'.format(row.last_modifier?.firstname); - node += ''; + if (row.last_modifier) { + let node = '%s'.format(escape_str(row.last_modifier?.patron_id), escape_str(row.last_modifier?.surname)); + if (row.last_modifier?.firstname) node += ", %s".format(escape_str(row.last_modifier?.firstname)); + node += ""; return node; } return '' @@ -1490,17 +1490,17 @@ searchable: true, orderable: true, render: function (data, type, row, meta) { - let node = ''; - if(row.status === 'ASKED') node += '%s'.format(_("Pending")); - else if(row.status === 'ACCEPTED') node += '%s'.format(_("Accepted")); - else if(row.status === 'ORDERED') node += '%s'.format(_("Ordered")); - else if(row.status === 'REJECTED') node += '%s'.format(_("Rejected")); - else if(row.status === 'CHECKED') node += '%s'.format(_("Checked")); - else if(row.status === 'AVAILABLE') node += '%s'.format(_("Available")); - else if(row._strings.status.str) node += '%s'.format(row._strings.status.str); - else node += '%s'.format(_("Status unknown")); - if ( row.reason ) { - node += '
('+ row.reason +')
'; + let node = ""; + if (row.status === "ASKED") node += '%s'.format(escape_str(_("Pending"))); + else if (row.status === "ACCEPTED") node += '%s'.format(escape_str(_("Accepted"))); + else if (row.status === "ORDERED") node += '%s'.format(escape_str(_("Ordered"))); + else if (row.status === "REJECTED") node += '%s'.format(escape_str(_("Rejected"))); + else if (row.status === "CHECKED") node += '%s'.format(escape_str(_("Checked"))); + else if (row.status === "AVAILABLE") node += '%s'.format(escape_str(_("Available"))); + else if (row._strings.status.str) node += '%s'.format(escape_str(row._strings.status.str)); + else node += '%s'.format(escape_str(_("Status unknown"))); + if (row.reason) { + node += '
(' + escape_str(row.reason) + ")
"; } return node; }, @@ -1512,21 +1512,21 @@ render: function (data, type, row, meta) { [% IF CAN_user_suggestions_suggestions_manage %] let node = '
' - node += ' %s'.format(row.suggestion_id, _("Edit")) - node += ''.format(row.suggestion_id) - node += '
' return node [% ELSIF CAN_user_suggestions_suggestions_delete %] - return ''.format(row.suggestion_id, _("Delete")) + return ''.format(escape_str(row.suggestion_id), escape_str(_("Delete")() [% END %] }, createdCell: function (cell, cellData, rowData, rowIndex, colIndex) {