From ebb5e3fe6542e721c6794bc7074252583350ca41 Mon Sep 17 00:00:00 2001 From: Aditya Toshniwal Date: Fri, 21 Jun 2019 09:53:57 +0100 Subject: [PATCH] Ensure Python escaping matched JS escaping and fix a minor XSS issue in the Query Tool that required superuser access to trigger. Fixes #4378 --- docs/en_US/release_notes_4_9.rst | 1 + web/pgadmin/browser/utils.py | 25 +++++++++++++++++++ web/pgadmin/tools/datagrid/__init__.py | 4 ++- .../tools/datagrid/static/js/datagrid.js | 2 +- 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/docs/en_US/release_notes_4_9.rst b/docs/en_US/release_notes_4_9.rst index 7bf210494..975af149c 100644 --- a/docs/en_US/release_notes_4_9.rst +++ b/docs/en_US/release_notes_4_9.rst @@ -39,4 +39,5 @@ Bug fixes | `Bug #4362 `_ - Remove additional "SETOF" included when generating CREATE scripts for trigger functions. | `Bug #4365 `_ - Fix help links for backup globals and backup server. | `Bug #4367 `_ - Fix an XSS issue seen in View/Edit data mode if a column name includes HTML. +| `Bug #4378 `_ - Ensure Python escaping matched JS escaping and fix a minor XSS issue in the Query Tool that required superuser access to trigger. | `Bug #4380 `_ - Ensure that both columns and partitions can be edited at the same time in the table dialog. \ No newline at end of file diff --git a/web/pgadmin/browser/utils.py b/web/pgadmin/browser/utils.py index 0462d7e35..4c049bedb 100644 --- a/web/pgadmin/browser/utils.py +++ b/web/pgadmin/browser/utils.py @@ -22,6 +22,31 @@ from pgadmin.utils.exception import ConnectionLost, SSHTunnelConnectionLost,\ CryptKeyMissing +def underscore_escape(text): + """ + This function mimics the behaviour of underscore js escape function + The html escaped by jinja is not compatible for underscore unescape + function + :param text: input html text + :return: escaped text + """ + html_map = { + '&': "&", + '<': "<", + '>': ">", + '"': """, + '`': "`", + "'": "'" + } + + # always replace & first + for c, r in sorted(html_map.items(), + key=lambda x: 0 if x[0] == '&' else 1): + text = text.replace(c, r) + + return text + + def is_version_in_range(sversion, min_ver, max_ver): assert (max_ver is None or isinstance(max_ver, int)) assert (min_ver is None or isinstance(min_ver, int)) diff --git a/web/pgadmin/tools/datagrid/__init__.py b/web/pgadmin/tools/datagrid/__init__.py index c0f61e9f0..fbc842fc7 100644 --- a/web/pgadmin/tools/datagrid/__init__.py +++ b/web/pgadmin/tools/datagrid/__init__.py @@ -30,6 +30,8 @@ from pgadmin.utils.driver import get_driver from pgadmin.utils.exception import ConnectionLost, SSHTunnelConnectionLost from pgadmin.utils.preferences import Preferences from pgadmin.settings import get_setting +from pgadmin.browser.utils import underscore_escape + query_tool_close_session_lock = Lock() @@ -304,7 +306,7 @@ def panel(trans_id, is_query_tool, editor_title): _=gettext, uniqueId=trans_id, is_query_tool=is_query_tool, - editor_title=editor_title, + editor_title=underscore_escape(editor_title), script_type_url=sURL, is_desktop_mode=app.PGADMIN_RUNTIME, is_linux=is_linux_platform, diff --git a/web/pgadmin/tools/datagrid/static/js/datagrid.js b/web/pgadmin/tools/datagrid/static/js/datagrid.js index 5910fc435..b7d64de41 100644 --- a/web/pgadmin/tools/datagrid/static/js/datagrid.js +++ b/web/pgadmin/tools/datagrid/static/js/datagrid.js @@ -313,7 +313,7 @@ define('pgadmin.datagrid', [ var queryToolPanel = pgBrowser.docker.addPanel('frm_datagrid', wcDocker.DOCK.STACKED, propertiesPanel[0]); // Set panel title and icon - queryToolPanel.title(''+panel_title+''); + queryToolPanel.title(''+_.escape(panel_title)+''); queryToolPanel.icon(panel_icon); queryToolPanel.focus();