about summary refs log tree commit diff
path: root/pkgs
diff options
context:
space:
mode:
authorRobert Scott <code@humanleg.org.uk>2024-04-10 22:07:21 +0100
committerGitHub <noreply@github.com>2024-04-10 22:07:21 +0100
commit14289ac5e602222f7c2dac998159c8262fb962db (patch)
treeeaac7c02c7e064d5ca2e8ddd8be629e35498232f /pkgs
parent01a58b59c752994b8bc7d7f2101d06360eb4e4cb (diff)
parent3006e433c0e554e54c9d6eb1e639a951ff57752d (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.patch199
-rw-r--r--pkgs/tools/admin/pgadmin/default.nix1
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 = ''