Bug 42904: Prevent XSS in patron restriction comments

Test plan

1. Search for a patron and open the patron details page.
2. Under "Patron restrictions", add a manual restriction with the following comment:
   <img src=x onerror="alert(document.domain)">
3. Save the restriction.
4. Navigate to the patron checkouts page:
   /cgi-bin/koha/circ/circulation.pl?borrowernumber=xxx
   Verify that the JavaScript payload executes.
5. Edit the patron record:
   /cgi-bin/koha/members/memberentry.pl?op=edit_form&destination=circ&borrowernumber=xxx
   Verify that the JavaScript payload executes.
6. For OPAC - Go to OPAC Verify that the JavaScript payload executes - /cgi-bin/koha/opac-user.pl
7. Apply the patch.
8. Repeat steps 4, 5 and 6.
9. Verify that:
   1. No JavaScript is executed.
   2. The page loads normally without any alert dialog. Applicable for both the staff and opac.

Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Wainui Witika-Park <wainuiwitikapark@catalyst.net.nz>
This commit is contained in:
Amit Gupta 2026-06-30 20:26:19 +05:30 committed by Wainui Witika-Park
parent 787343b8d9
commit b0def4443d
No known key found for this signature in database
GPG Key ID: 2D0A6AB5DAF1B78D
4 changed files with 12 additions and 8 deletions

View File

@ -1,5 +1,6 @@
[% USE raw %] [% USE raw %]
[% USE Koha %] [% USE Koha %]
[% USE HtmlScrubber %]
[% PROCESS 'restriction-types.inc' %] [% PROCESS 'restriction-types.inc' %]
[% IF ( patron.restrictions.count == 0 ) %] [% IF ( patron.restrictions.count == 0 ) %]
@ -23,9 +24,9 @@
<td> [% PROCESS restriction_type_description restriction_type=restriction.type %] </td> <td> [% PROCESS restriction_type_description restriction_type=restriction.type %] </td>
<td> <td>
[% IF restriction.comment.search('OVERDUES_PROCESS') %] [% IF restriction.comment.search('OVERDUES_PROCESS') %]
<span>Restriction added by overdues process [% restriction.comment.remove('OVERDUES_PROCESS ') | $raw %]</span> <span>Restriction added by overdues process [% restriction.comment.remove('OVERDUES_PROCESS ') | scrub_html type => 'comment' | $raw %]</span>
[% ELSE %] [% ELSE %]
[% restriction.comment | $raw %] [% restriction.comment | scrub_html type => 'comment' | $raw %]
[% END %] [% END %]
</td> </td>
<td> <td>

View File

@ -1,5 +1,6 @@
[% USE raw %] [% USE raw %]
[% USE Branches %] [% USE Branches %]
[% USE HtmlScrubber %]
[% USE Categories %] [% USE Categories %]
[% SET ClaimReturnedWarningThreshold = Koha.Preference('ClaimReturnedWarningThreshold') || 0 %] [% SET ClaimReturnedWarningThreshold = Koha.Preference('ClaimReturnedWarningThreshold') || 0 %]
[% SET return_claims = patron.return_claims %] [% SET return_claims = patron.return_claims %]
@ -104,10 +105,10 @@
[% END %] [% END %]
</span> </span>
[% IF restriction.comment.search('OVERDUES_PROCESS') %] [% IF restriction.comment.search('OVERDUES_PROCESS') %]
Restriction added by overdues process [% restriction.comment.remove('OVERDUES_PROCESS ') | $raw | html_line_break %] Restriction added by overdues process [% restriction.comment.remove('OVERDUES_PROCESS ') | scrub_html type => 'comment' | $raw | html_line_break %]
[% ELSE %] [% ELSE %]
[% IF restriction.comment %] [% IF restriction.comment %]
<span class="restriction_detail">[%- restriction.comment | html_line_break -%]</span> <span class="restriction_detail">[%- restriction.comment | scrub_html type => 'comment' | html_line_break -%]</span>
[% END %] [% END %]
[% END %] [% END %]
<span class="restriction_type">([%- restriction.type.display_text | html -%])</span> <span class="restriction_type">([%- restriction.type.display_text | html -%])</span>

View File

@ -3,6 +3,7 @@
[% USE To %] [% USE To %]
[% USE Koha %] [% USE Koha %]
[% USE KohaDates %] [% USE KohaDates %]
[% USE HtmlScrubber %]
[% USE Branches %] [% USE Branches %]
[% PROCESS 'member-main-address-style.inc' %] [% PROCESS 'member-main-address-style.inc' %]
[% PROCESS 'member-alt-address-style.inc' %] [% PROCESS 'member-alt-address-style.inc' %]
@ -1390,9 +1391,9 @@
<td>[% PROCESS restriction_type_description restriction_type=restriction.type %]</td> <td>[% PROCESS restriction_type_description restriction_type=restriction.type %]</td>
<td> <td>
[% IF restriction.comment.search('OVERDUES_PROCESS') %] [% IF restriction.comment.search('OVERDUES_PROCESS') %]
Restriction added by overdues process [% restriction.comment.remove('OVERDUES_PROCESS ') | $raw %] Restriction added by overdues process [% restriction.comment.remove('OVERDUES_PROCESS ') | scrub_html type => 'comment' | $raw %]
[% ELSE %] [% ELSE %]
[% restriction.comment | $raw %] [% restriction.comment | scrub_html type => 'comment' | $raw %]
[% END %] [% END %]
</td> </td>
<td> <td>

View File

@ -1,3 +1,4 @@
[% USE HtmlScrubber %]
<li class="userdebarred blocker"> <li class="userdebarred blocker">
<strong>Your account has been frozen</strong> <strong>Your account has been frozen</strong>
<ul> <ul>
@ -11,10 +12,10 @@
[% END %] [% END %]
</span> </span>
[% IF restriction.comment.search('OVERDUES_PROCESS') %] [% IF restriction.comment.search('OVERDUES_PROCESS') %]
<span class="restriction_detail">Restriction added by overdues process [% restriction.comment.remove('OVERDUES_PROCESS ') | $raw | html_line_break %]</span> <span class="restriction_detail">Restriction added by overdues process [% restriction.comment.remove('OVERDUES_PROCESS ') | scrub_html type => 'comment' | $raw | html_line_break %]</span>
[% ELSE %] [% ELSE %]
[% IF restriction.comment %] [% IF restriction.comment %]
<span class="restriction_detail">[%- restriction.comment | html_line_break -%]</span> <span class="restriction_detail">[%- restriction.comment | scrub_html type => 'comment' | html_line_break -%]</span>
[% END %] [% END %]
[% END %] [% END %]
</li> </li>