Bug 34761: Prevent XSS for searches and saved search filters

</script> tags are interpreted in JSON strings as HTML, which can
lead to XSS attacks.

This patch puts HTML escaped JSON in the value of a hidden HTML element.
The Javascript then takes the value as a string, parses it as JSON,
and is able to use it to save search filters without triggering a
XSS attack.

This patch also adds DataTable's built-in HTML escaping for the query
and limits on the admin UI for the search filters.

Test plan:
0. Apply patch
1. Go to
http://localhost:8081/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=SavedSearchFilters
2. Enable the system preference
3. Go to http://localhost:8081/cgi-bin/koha/catalogue/search.pl?q=e
4. Click "Save search as filter"
5. Checkbox "Show in staff interface?"
6. Type "E-TEST" into box and click 'Save'
7. Go to
http://localhost:8081/cgi-bin/koha/catalogue/search.pl?q=e
8. Click "E-TEST" under "Custom search filters"
9. Note that you see search results
10. Go to
http://localhost:8081/cgi-bin/koha/admin/search_filters.pl
11. Note that for "E-TEST" you see a "Query" like
{"operators":[],"operands":["e"],"indexes":[]}
12. Note that for "E-TEST" you see a "Limits" like
{"limits":[]}

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
David Cook 2023-09-13 01:33:43 +00:00 committed by Tomas Cohen Arazi
parent dcd698a4b4
commit 4e32b76198
Signed by: tomascohen
GPG key ID: 0A272EA1B2F3C15F
2 changed files with 8 additions and 4 deletions

View file

@ -119,12 +119,14 @@
{
"data": "query",
"searchable": true,
"orderable": true
"orderable": true,
"render": jQuery.fn.DataTable.render.text()
},
{
"data": "limits",
"searchable": true,
"orderable": true
"orderable": true,
"render": jQuery.fn.DataTable.render.text()
},
{
"data": "opac",

View file

@ -797,6 +797,8 @@
</div> <!-- /.col-sm-2.col-sm-pull-10 -->
</div> <!-- /.row -->
<input type="hidden" id="query_json" value="[% query_json | html %]">
<input type="hidden" id="limit_json" value="[% limit_json | html %]">
[% MACRO jsinclude BLOCK %]
[% Asset.js("js/browser.js") | $raw %]
[% Asset.js("lib/hc-sticky.js") | $raw %]
@ -837,8 +839,8 @@
query_desc: "[% To.json( query_desc ) | html %]",
query_cgi: "[% query_cgi | html %]",
limit_cgi: "[% limit_cgi | html %]",
query_json: [% query_json | $raw %],
limit_json: [% limit_json | $raw %],
query_json: JSON.parse($('#query_json').val()),
limit_json: JSON.parse($('#limit_json').val()),
sort_by: "[% sort_by | html %]",
gotoPage: "[% gotoPage | html %]",
gotoNumber: "[% gotoNumber | html %]",