From 5e8a75cdf9b62b672129c4d5b982ef8dbd3e8f50 Mon Sep 17 00:00:00 2001 From: Pravesh Sharma Date: Wed, 4 Dec 2024 15:42:45 +0530 Subject: [PATCH] Added escaping for the placeholder parameters before passing it to the passexec command. #6794 --- .../server_groups/servers/static/js/server.ui.js | 1 + web/pgadmin/utils/passexec.py | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.ui.js b/web/pgadmin/browser/server_groups/servers/static/js/server.ui.js index a6a619aa2a1..8ea3cf18972 100644 --- a/web/pgadmin/browser/server_groups/servers/static/js/server.ui.js +++ b/web/pgadmin/browser/server_groups/servers/static/js/server.ui.js @@ -349,6 +349,7 @@ export default class ServerSchema extends BaseUISchema { group: gettext('Advanced'), controlProps: {maxLength: null}, mode: ['properties', 'edit', 'create'], disabled: pgAdmin.server_mode == 'True' && pgAdmin.enable_server_passexec_cmd == 'False', + helpMessage: gettext('The server hostname, port, and username can be passed as variables by using the placeholders %HOST%, %PORT%, and %USERNAME%, which will be replaced with the corresponding server connection information.') }, { id: 'passexec_expiration', label: gettext('Password exec expiration (seconds)'), type: 'int', diff --git a/web/pgadmin/utils/passexec.py b/web/pgadmin/utils/passexec.py index 189b15c7dc3..9f28e32347c 100644 --- a/web/pgadmin/utils/passexec.py +++ b/web/pgadmin/utils/passexec.py @@ -14,6 +14,7 @@ from flask import current_app import config +from pgadmin.utils.driver import get_driver class PasswordExec: @@ -22,9 +23,9 @@ class PasswordExec: def __init__(self, cmd, host, port, username, expiration_seconds=None, timeout=60): - cmd = str(cmd).replace('%HOSTNAME%', host) - cmd = cmd.replace('%PORT%', str(port)) - cmd = cmd.replace('%USERNAME%', username) + self.host = host + self.port = port + self.username = username self.cmd = cmd self.expiration_seconds = int(expiration_seconds) \ if expiration_seconds is not None else None @@ -36,6 +37,12 @@ def get(self): if config.SERVER_MODE and not config.ENABLE_SERVER_PASS_EXEC_CMD: # Arbitrary shell execution on server is a security risk raise NotImplementedError('Passexec not available in server mode') + driver = get_driver(config.PG_DEFAULT_DRIVER) + self.cmd = str(self.cmd) + self.cmd = self.cmd.replace('%HOSTNAME%', self.host) + self.cmd = self.cmd.replace('%PORT%', str(self.port)) + self.cmd = self.cmd.replace('%USERNAME%', + driver.qtIdent(None,self.username)) with self.lock: if not self.password or self.is_expired(): if not self.cmd: