From 2cb4d0d6237125d8f0a4c9b8e7671e2726f48a56 Mon Sep 17 00:00:00 2001
From: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Date: Wed, 17 Mar 2021 11:38:47 +0100
Subject: [PATCH] Bug 27942: Prevent XSS vulnerabilities in quote-upload
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When uploading new quotes the JS variables are not escaped correctly.

Test plan:
Create a new file with the following content (remove the first and last lines containing """):
"""
":this is a source","this is a text"
"this is another ❤one","and another text❤"
"this <script>alert('foo');</script>","and <script>alert('❤');</script>"
"""

Go to Home › Tools › Quote editor
Click Import quote
Select the file
Edit the third line, hit enter
Import quotes

Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
---
 .../intranet-tmpl/prog/en/modules/tools/quotes-upload.tt   | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/quotes-upload.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/quotes-upload.tt
index 867a3628c3..c9961bc2fb 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/quotes-upload.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/quotes-upload.tt
@@ -157,6 +157,8 @@
             // then default to comma.
             strDelimiter = (strDelimiter || ",");
 
+            strData = escape_str(strData);
+
             // Create a regular expression to parse the CSV values.
             var objPattern = new RegExp(
             (
@@ -280,6 +282,7 @@
                "fnDrawCallback": function(oSettings) {
                     /* Apply the jEditable handlers to the table on all fields w/o the no_edit id */
                     $('#quotes_editor tbody td[id!="no_edit"]').editable( function(value, settings) {
+                            value = escape_str(value);
                             var cellPosition = oTable.fnGetPosition( this );
                             oTable.fnUpdate(value, cellPosition[0], cellPosition[1], false, false);
                             return(value);
@@ -346,7 +349,9 @@
         function fnGetData(element) {
             var lines = oTable.fnGetData();
             $(lines).each(function(line){
-                var data = {source: this[1], text: this[2]};
+                var s = this[1].replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
+                var t = this[2].replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
+                var data = {source: s, text: t};
                 var success = 0; var error = 0;
                 $.ajax({
                     url      : "/api/v1/quotes",
-- 
2.20.1