diff options
author | Robert Scott <code@humanleg.org.uk> | 2024-04-10 22:07:21 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-10 22:07:21 +0100 |
commit | 14289ac5e602222f7c2dac998159c8262fb962db (patch) | |
tree | eaac7c02c7e064d5ca2e8ddd8be629e35498232f /pkgs | |
parent | 01a58b59c752994b8bc7d7f2101d06360eb4e4cb (diff) | |
parent | 3006e433c0e554e54c9d6eb1e639a951ff57752d (diff) |
Merge pull request #302428 from LeSuisse/pgadin4-CVE-2024-3116-23.11
[23.11] pgadmin4: backport fix for CVE-2024-3116
Diffstat (limited to 'pkgs')
-rw-r--r-- | pkgs/tools/admin/pgadmin/CVE-2024-3116.patch | 199 | ||||
-rw-r--r-- | pkgs/tools/admin/pgadmin/default.nix | 1 |
2 files changed, 200 insertions, 0 deletions
diff --git a/pkgs/tools/admin/pgadmin/CVE-2024-3116.patch b/pkgs/tools/admin/pgadmin/CVE-2024-3116.patch new file mode 100644 index 0000000000000..4e0f46825a006 --- /dev/null +++ b/pkgs/tools/admin/pgadmin/CVE-2024-3116.patch @@ -0,0 +1,199 @@ +From c98e3969a1c2aa4c41578ad3d811b77a75b42abf Mon Sep 17 00:00:00 2001 +From: Khushboo Vashi <khushboo.vashi@enterprisedb.com> +Date: Mon, 1 Apr 2024 11:34:01 +0530 +Subject: [PATCH] Fixed a remote code execution issue in the validate binary + path (CVE-2024-3116). #7326 + +(cherry picked from commit fbbbfe22dd468bcfef1e1f833ec32289a6e56a8b) +--- + web/config.py | 20 +++++++++++++++++++ + .../servers/static/js/binary_path.ui.js | 4 ++++ + .../browser/server_groups/servers/types.py | 16 ++++++++++----- + .../browser/templates/browser/js/utils.js | 2 ++ + web/pgadmin/misc/__init__.py | 7 ++++++- + web/pgadmin/utils/__init__.py | 14 +++++++++++-- + 6 files changed, 55 insertions(+), 8 deletions(-) + +diff --git a/web/config.py b/web/config.py +index e1a125437..5ea247909 100644 +--- a/web/config.py ++++ b/web/config.py +@@ -492,6 +492,26 @@ DEFAULT_BINARY_PATHS = { + "ppas-16": "" + } + ++########################################################################## ++ ++# Admin can specify fixed binary paths to prevent users from changing. ++# It will take precedence over DEFAULT_BINARY_PATHS. ++ ++FIXED_BINARY_PATHS = { ++ "pg": "", ++ "pg-12": "", ++ "pg-13": "", ++ "pg-14": "", ++ "pg-15": "", ++ "pg-16": "", ++ "ppas": "", ++ "ppas-12": "", ++ "ppas-13": "", ++ "ppas-14": "", ++ "ppas-15": "", ++ "ppas-16": "" ++} ++ + ########################################################################## + # Test settings - used primarily by the regression suite, not for users + ########################################################################## +diff --git a/web/pgadmin/browser/server_groups/servers/static/js/binary_path.ui.js b/web/pgadmin/browser/server_groups/servers/static/js/binary_path.ui.js +index ae2dadb22..939eb14ff 100644 +--- a/web/pgadmin/browser/server_groups/servers/static/js/binary_path.ui.js ++++ b/web/pgadmin/browser/server_groups/servers/static/js/binary_path.ui.js +@@ -50,6 +50,10 @@ export default class BinaryPathSchema extends BaseUISchema { + { + id: 'binaryPath', label: gettext('Binary Path'), cell: 'file', type: 'file', + isvalidate: true, ++ disabled: function (state) { ++ // If Fixed path is assigned, user will not able to edit it. ++ return state?.isFixed ? state.isFixed : false; ++ }, + controlProps: { + dialogType: 'select_folder', + supportedTypes: ['*', 'sql', 'backup'], +diff --git a/web/pgadmin/browser/server_groups/servers/types.py b/web/pgadmin/browser/server_groups/servers/types.py +index 9e64495ac..3f8101d85 100644 +--- a/web/pgadmin/browser/server_groups/servers/types.py ++++ b/web/pgadmin/browser/server_groups/servers/types.py +@@ -11,7 +11,6 @@ import os + import json + import config + import copy +- + from flask import render_template + from flask_babel import gettext as _ + from pgadmin.utils.preferences import Preferences +@@ -240,15 +239,22 @@ class ServerType(): + """ + is_default_path_set = ServerType.is_default_binary_path_set(bin_paths) + for path in config.DEFAULT_BINARY_PATHS: +- path_value = config.DEFAULT_BINARY_PATHS[path] ++ is_fixed_path = (path in config.FIXED_BINARY_PATHS and ++ config.FIXED_BINARY_PATHS[path] != '' and ++ config.FIXED_BINARY_PATHS[path] is not None) ++ path_value = (is_fixed_path and config.FIXED_BINARY_PATHS[path] ++ ) or config.DEFAULT_BINARY_PATHS[path] ++ + if path_value is not None and path_value != "" and \ + path.find(server_type) == 0 and len(path.split('-')) > 1: +- set_binary_path(path_value, bin_paths, server_type, +- path.split('-')[1]) ++ set_binary_path( ++ path_value, bin_paths, server_type, path.split('-')[1], ++ is_fixed_path=is_fixed_path) + elif path_value is not None and path_value != "" and \ + path.find(server_type) == 0: + set_binary_path(path_value, bin_paths, server_type, +- set_as_default=not is_default_path_set) ++ set_as_default=not is_default_path_set, ++ is_fixed_path=is_fixed_path) + + + # Default Server Type +diff --git a/web/pgadmin/browser/templates/browser/js/utils.js b/web/pgadmin/browser/templates/browser/js/utils.js +index 23321c443..9e17648bb 100644 +--- a/web/pgadmin/browser/templates/browser/js/utils.js ++++ b/web/pgadmin/browser/templates/browser/js/utils.js +@@ -65,6 +65,8 @@ define('pgadmin.browser.utils', + /* GET Binary Path Browse config */ + pgAdmin['enable_binary_path_browsing'] = '{{ current_app.config.get('ENABLE_BINARY_PATH_BROWSING') }}' == 'True'; + ++ pgAdmin['fixed_binary_paths'] = {{ current_app.config.get('FIXED_BINARY_PATHS') }}; ++ + /* GET the pgadmin server's locale */ + pgAdmin['pgadmin_server_locale'] = '{{pgadmin_server_locale}}'; + +diff --git a/web/pgadmin/misc/__init__.py b/web/pgadmin/misc/__init__.py +index 451271e07..4262d0504 100644 +--- a/web/pgadmin/misc/__init__.py ++++ b/web/pgadmin/misc/__init__.py +@@ -13,6 +13,7 @@ from pgadmin.utils import driver + from flask import url_for, render_template, Response, request, current_app + from flask_babel import gettext + from flask_security import login_required ++from pathlib import Path + from pgadmin.utils import PgAdminModule, replace_binary_path, \ + get_binary_path_versions + from pgadmin.utils.csrf import pgCSRFProtect +@@ -254,7 +255,11 @@ def validate_binary_path(): + data = json.loads(data) + + version_str = '' +- if 'utility_path' in data and data['utility_path'] is not None: ++ ++ # Do not allow storage dir as utility path ++ if 'utility_path' in data and data['utility_path'] is not None and \ ++ Path(config.STORAGE_DIR) != Path(data['utility_path']) and \ ++ Path(config.STORAGE_DIR) not in Path(data['utility_path']).parents: + binary_versions = get_binary_path_versions(data['utility_path']) + for utility, version in binary_versions.items(): + if version is None: +diff --git a/web/pgadmin/utils/__init__.py b/web/pgadmin/utils/__init__.py +index 15fc9eb5c..98ac7d85f 100644 +--- a/web/pgadmin/utils/__init__.py ++++ b/web/pgadmin/utils/__init__.py +@@ -14,13 +14,13 @@ import subprocess + from collections import defaultdict + from operator import attrgetter + ++from pathlib import Path + from flask import Blueprint, current_app, url_for + from flask_babel import gettext + from flask_security import current_user, login_required + from flask_security.utils import get_post_login_redirect, \ + get_post_logout_redirect + from threading import Lock +- + from .paths import get_storage_directory + from .preferences import Preferences + from pgadmin.utils.constants import UTILITIES_ARRAY, USER_NOT_FOUND, \ +@@ -330,11 +330,18 @@ def does_utility_exist(file): + :return: + """ + error_msg = None ++ + if file is None: + error_msg = gettext("Utility file not found. Please correct the Binary" + " Path in the Preferences dialog") + return error_msg + ++ if Path(current_app.config['STORAGE_DIR']) == Path(file) or \ ++ Path(current_app.config['STORAGE_DIR']) in Path(file).parents: ++ error_msg = gettext("Please correct the Binary Path in the Preferences" ++ " dialog. pgAdmin storage directory can not be a" ++ " utility binary directory.") ++ + if not os.path.exists(file): + error_msg = gettext("'%s' file not found. Please correct the Binary" + " Path in the Preferences dialog" % file) +@@ -386,7 +393,8 @@ def get_binary_path_versions(binary_path: str) -> dict: + + + def set_binary_path(binary_path, bin_paths, server_type, +- version_number=None, set_as_default=False): ++ version_number=None, set_as_default=False, ++ is_fixed_path=False): + """ + This function is used to iterate through the utilities and set the + default binary path. +@@ -416,6 +424,8 @@ def set_binary_path(binary_path, bin_paths, server_type, + if path_with_dir is not None else binary_path + if set_as_default: + path['isDefault'] = True ++ # Whether the fixed path in the config file exists or not ++ path['isFixed'] = is_fixed_path + break + break + except Exception: +-- +2.44.0 + diff --git a/pkgs/tools/admin/pgadmin/default.nix b/pkgs/tools/admin/pgadmin/default.nix index 787736d7f46ed..6767425cf381f 100644 --- a/pkgs/tools/admin/pgadmin/default.nix +++ b/pkgs/tools/admin/pgadmin/default.nix @@ -109,6 +109,7 @@ pythonPackages.buildPythonApplication rec { hash = "sha256-uIOWefMjbequVfS6haJeSbXv/I6ZdA7uCEwCZSnCtRM="; excludes = [ "docs/en_US/release_notes_8_4.rst" ]; }) + ./CVE-2024-3116.patch ]; postPatch = '' |