Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP3:Update
pgadmin4
0001-Ensure-that-the-authenticated-users-cant-a...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-Ensure-that-the-authenticated-users-cant-access-each-other-directories.patch of Package pgadmin4
From 8b236e7bc8238a2b90ae1524eef2ce120f53ad9d Mon Sep 17 00:00:00 2001 From: Aditya Toshniwal <aditya.toshniwal@enterprisedb.com> Date: Fri, 13 Jan 2023 12:29:21 +0530 Subject: [PATCH] Ensure that the authenticated users can't access each other's directories and files by providing relative paths. #5734 Rebased by Antonio Larrosa <alarrosa@suse.com> for pgAdmin 4.30 --- web/pgadmin/tools/backup/__init__.py | 41 ++-------- web/pgadmin/tools/import_export/__init__.py | 36 ++------- .../tools/import_export_servers/__init__.py | 13 +++- web/pgadmin/tools/restore/__init__.py | 30 ++------ web/pgadmin/utils/__init__.py | 75 ++++++++++++------- web/yarn.lock | 8 +- 6 files changed, 77 insertions(+), 126 deletions(-) diff --git a/web/pgadmin/tools/backup/__init__.py b/web/pgadmin/tools/backup/__init__.py index 0a0567d072..6b27b38aeb 100644 --- a/web/pgadmin/tools/backup/__init__.py +++ b/web/pgadmin/tools/backup/__init__.py @@ -19,8 +19,9 @@ from flask_security import login_required, current_user from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc from pgadmin.utils import PgAdminModule, get_storage_directory, html, \ #- fs_short_path, document_dir, does_utility_exist, get_server - fs_short_path, document_dir, does_utility_exist -from pgadmin.utils.ajax import make_json_response, bad_request #+ fs_short_path, document_dir, does_utility_exist, get_server, \ + fs_short_path, document_dir, does_utility_exist, \ + filename_with_file_manager_path +from pgadmin.utils.ajax import make_json_response, bad_request, unauthorized from config import PG_DEFAULT_DRIVER # from pgadmin.model import Server, SharedServer from pgadmin.model import Server @@ -189,40 +190,6 @@ def script(): ) -def filename_with_file_manager_path(_file, create_file=True): - """ - Args: - file: File name returned from client file manager - create_file: Set flag to False when file creation doesn't required - Returns: - Filename to use for backup with full path taken from preference - """ - # Set file manager directory from preference - storage_dir = get_storage_directory() - if storage_dir: - _file = os.path.join(storage_dir, _file.lstrip('/').lstrip('\\')) - elif not os.path.isabs(_file): - _file = os.path.join(document_dir(), _file) - - def short_filepath(): - short_path = fs_short_path(_file) - # fs_short_path() function may return empty path on Windows - # if directory doesn't exists. In that case we strip the last path - # component and get the short path. - if os.name == 'nt' and short_path == '': - base_name = os.path.basename(_file) - dir_name = os.path.dirname(_file) - short_path = fs_short_path(dir_name) + '\\' + base_name - return short_path - - if create_file: - # Touch the file to get the short path of the file on windows. - with open(_file, 'a'): - return short_filepath() - - return short_filepath() - - def _get_args_params_values(data, conn, backup_obj_type, backup_file, server, manager): """ @@ -367,6 +334,8 @@ def create_backup_objects_job(sid): try: backup_file = filename_with_file_manager_path( data['file'], (data.get('format', '') != 'directory')) + except PermissionError as e: + return unauthorized(errormsg=str(e)) except Exception as e: return bad_request(errormsg=str(e)) diff --git a/web/pgadmin/tools/import_export/__init__.py b/web/pgadmin/tools/import_export/__init__.py index db1e0d2622..6308f9dbfd 100644 --- a/web/pgadmin/tools/import_export/__init__.py +++ b/web/pgadmin/tools/import_export/__init__.py @@ -17,8 +17,9 @@ from flask_security import login_required, current_user from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc from pgadmin.utils import PgAdminModule, get_storage_directory, html, \ - fs_short_path, document_dir, IS_WIN, does_utility_exist -from pgadmin.utils.ajax import make_json_response, bad_request + fs_short_path, document_dir, IS_WIN, does_utility_exist, \ + filename_with_file_manager_path +from pgadmin.utils.ajax import make_json_response, bad_request, unauthorized from config import PG_DEFAULT_DRIVER from pgadmin.model import Server @@ -145,33 +146,6 @@ def script(): ) -def filename_with_file_manager_path(_file, _present=False): - """ - Args: - file: File name returned from client file manager - - Returns: - Filename to use for backup with full path taken from preference - """ - # Set file manager directory from preference - storage_dir = get_storage_directory() - - if storage_dir: - _file = os.path.join(storage_dir, _file.lstrip('/').lstrip('\\')) - elif not os.path.isabs(_file): - _file = os.path.join(document_dir(), _file) - - if not _present: - # Touch the file to get the short path of the file on windows. - with open(_file, 'a'): - return fs_short_path(_file) - else: - if not os.path.isfile(_file): - return None - - return fs_short_path(_file) - - def _get_ignored_column_list(data, driver, conn): """ Get list of ignored columns for import/export. @@ -297,7 +271,9 @@ def create_import_export_job(sid): if 'filename' in data: try: _file = filename_with_file_manager_path( - data['filename'], data['is_import']) + data['filename'], not data['is_import']) + except PermissionError as e: + return unauthorized(errormsg=str(e)) except Exception as e: return bad_request(errormsg=str(e)) #diff --git a/web/pgadmin/tools/import_export_servers/__init__.py b/web/pgadmin/tools/import_export_servers/__init__.py #index 755507774c..91ec2ac62a 100644 #--- a/web/pgadmin/tools/import_export_servers/__init__.py #+++ b/web/pgadmin/tools/import_export_servers/__init__.py #@@ -20,10 +20,11 @@ # from pgadmin.utils import PgAdminModule # from pgadmin.utils.ajax import bad_request # from pgadmin.utils.constants import MIMETYPE_APP_JS #-from pgadmin.utils.ajax import make_json_response, internal_server_error #+from pgadmin.utils.ajax import make_json_response, internal_server_error, \ #+ unauthorized # from pgadmin.model import ServerGroup, Server # from pgadmin.utils import clear_database_servers, dump_database_servers,\ #- load_database_servers, validate_json_data #+ load_database_servers, validate_json_data, filename_with_file_manager_path # from urllib.parse import unquote # from pgadmin.utils.paths import get_storage_directory # #@@ -118,6 +119,14 @@ def load_servers(): # # # retrieve storage directory path # storage_manager_path = get_storage_directory() #+ #+ try: #+ file_path = filename_with_file_manager_path(file_path) #+ except PermissionError as e: #+ return unauthorized(errormsg=str(e)) #+ except Exception as e: #+ return bad_request(errormsg=str(e)) #+ # if storage_manager_path: # # generate full path of file # file_path = os.path.join( diff --git a/web/pgadmin/tools/restore/__init__.py b/web/pgadmin/tools/restore/__init__.py index 0a242bf847..fc2cb998fb 100644 --- a/web/pgadmin/tools/restore/__init__.py +++ b/web/pgadmin/tools/restore/__init__.py @@ -18,8 +18,10 @@ from flask_security import login_required, current_user from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc from pgadmin.utils import PgAdminModule, get_storage_directory, html, \ #- fs_short_path, document_dir, does_utility_exist, get_server - fs_short_path, document_dir, does_utility_exist -from pgadmin.utils.ajax import make_json_response, bad_request #+ fs_short_path, document_dir, does_utility_exist, get_server, \ + fs_short_path, document_dir, does_utility_exist, \ + filename_with_file_manager_path +from pgadmin.utils.ajax import make_json_response, bad_request, \ + internal_server_error from config import PG_DEFAULT_DRIVER # from pgadmin.model import Server, SharedServer from pgadmin.model import Server @@ -129,28 +131,6 @@ def script(): ) -def filename_with_file_manager_path(_file): - """ - Args: - file: File name returned from client file manager - - Returns: - Filename to use for backup with full path taken from preference - """ - # Set file manager directory from preference - storage_dir = get_storage_directory() - - if storage_dir: - _file = os.path.join(storage_dir, _file.lstrip('/').lstrip('\\')) - elif not os.path.isabs(_file): - _file = os.path.join(document_dir(), _file) - - if not os.path.isfile(_file) and not os.path.exists(_file): - return None - - return fs_short_path(_file) - - def _get_create_req_data(): """ Get data from request for create restore job. @@ -164,7 +144,7 @@ def _get_create_req_data(): try: _file = filename_with_file_manager_path(data['file']) except Exception as e: - return True, bad_request(errormsg=str(e)), data + return True, internal_server_error(errormsg=str(e)), data, None if _file is None: return True, make_json_response( diff --git a/web/pgadmin/utils/__init__.py b/web/pgadmin/utils/__init__.py index dbca361652..cd86c022fa 100644 --- a/web/pgadmin/utils/__init__.py +++ b/web/pgadmin/utils/__init__.py @@ -260,6 +260,45 @@ def get_complete_file_path(file, validate=True): # return file return file if os.path.isfile(file) else None +def filename_with_file_manager_path(_file, create_file=False, + skip_permission_check=False): + """ + Args: + file: File name returned from client file manager + create_file: Set flag to False when file creation doesn't required + Returns: + Filename to use for backup with full path taken from preference + """ + # Set file manager directory from preference + storage_dir = get_storage_directory() + + from pgadmin.misc.file_manager import Filemanager + Filemanager.check_access_permission( + storage_dir, _file, skip_permission_check) + if storage_dir: + _file = os.path.join(storage_dir, _file.lstrip('/').lstrip('\\')) + elif not os.path.isabs(_file): + _file = os.path.join(document_dir(), _file) + + def short_filepath(): + short_path = fs_short_path(_file) + # fs_short_path() function may return empty path on Windows + # if directory doesn't exists. In that case we strip the last path + # component and get the short path. + if os.name == 'nt' and short_path == '': + base_name = os.path.basename(_file) + dir_name = os.path.dirname(_file) + short_path = fs_short_path(dir_name) + '\\' + base_name + return short_path + + if create_file: + # Touch the file to get the short path of the file on windows. + with open(_file, 'a'): + return short_filepath() + + return short_filepath() + + def does_utility_exist(file): """ This function will check the utility file exists on given path. #@@ -434,27 +473,12 @@ def dump_database_servers(output_file, selected_servers, # # object_dict["Servers"] = server_dict # #- # retrieve storage directory path #- storage_manager_path = None #- if not from_setup: #- storage_manager_path = get_storage_directory(user) #- #- # generate full path of file #- file_path = unquote(output_file) #- #- from pgadmin.misc.file_manager import Filemanager # try: #- Filemanager.check_access_permission(storage_manager_path, file_path, #- from_setup) #+ file_path = filename_with_file_manager_path( #+ unquote(output_file), skip_permission_check=from_setup) # except Exception as e: # return _handle_error(str(e), from_setup) # #- if storage_manager_path is not None: #- file_path = os.path.join( #- storage_manager_path, #- file_path.lstrip('/').lstrip('\\') #- ) #- # # write to file # file_content = json.dumps(object_dict, indent=4) # error_str = "Error: {0}" #@@ -548,19 +572,12 @@ def load_database_servers(input_file, selected_servers, # if user is None: # return False, USER_NOT_FOUND % load_user # #- # retrieve storage directory path #- storage_manager_path = None #- if not from_setup: #- storage_manager_path = get_storage_directory(user) #- # # generate full path of file #- file_path = unquote(input_file) #- if storage_manager_path: #- # generate full path of file #- file_path = os.path.join( #- storage_manager_path, #- file_path.lstrip('/').lstrip('\\') #- ) #+ try: #+ file_path = filename_with_file_manager_path( #+ unquote(input_file), skip_permission_check=from_setup) #+ except Exception as e: #+ return _handle_error(str(e), from_setup) # # try: # with open(file_path) as f: diff --git a/web/yarn.lock b/web/yarn.lock index 96d52e5a29..df20a984a8 100644 --- a/web/yarn.lock +++ b/web/yarn.lock #@@ -8517,9 +8517,9 @@ react-checkbox-tree@^1.7.2: # nanoid "^3.0.0" # prop-types "^15.5.8" # #-"react-data-grid@git+https://github.com/EnterpriseDB/react-data-grid.git/#200d2f5e02de694e3e9ffbe177c279bc40240fb8": #+"react-data-grid@git+https://github.com/pgadmin-org/react-data-grid.git/#200d2f5e02de694e3e9ffbe177c279bc40240fb8": # version "7.0.0-beta.14" #- resolved "git+https://github.com/EnterpriseDB/react-data-grid.git/#200d2f5e02de694e3e9ffbe177c279bc40240fb8" #+ resolved "git+https://github.com/pgadmin-org/react-data-grid.git/#200d2f5e02de694e3e9ffbe177c279bc40240fb8" # dependencies: # clsx "^1.1.1" # @@ -10337,9 +10337,9 @@ watchpack@^2.4.0: # glob-to-regexp "^0.4.1" # graceful-fs "^4.1.2" chokidar "^3.4.1" watchpack-chokidar2 "^2.0.1" #-"webcabin-docker@git+https://github.com/EnterpriseDB/wcDocker/#3df8aac825ee2892f4d824de273b779cc6dbcad8": #+"webcabin-docker@git+https://github.com/pgadmin-org/wcdocker/#3df8aac825ee2892f4d824de273b779cc6dbcad8": -"webcabin-docker@git+https://github.com/EnterpriseDB/wcDocker/#c4a3398b89588408dc705895675bce7bd7660d36": +"webcabin-docker@git+https://github.com/pgadmin-org/wcDocker/#c4a3398b89588408dc705895675bce7bd7660d36": # version "2.2.5" version "2.2.4-dev" #- resolved "git+https://github.com/EnterpriseDB/wcDocker/#3df8aac825ee2892f4d824de273b779cc6dbcad8" #+ resolved "git+https://github.com/pgadmin-org/wcdocker/#3df8aac825ee2892f4d824de273b779cc6dbcad8" - resolved "git+https://github.com/EnterpriseDB/wcDocker/#c4a3398b89588408dc705895675bce7bd7660d36" + resolved "git+https://github.com/pgadmin-org/wcDocker/#c4a3398b89588408dc705895675bce7bd7660d36" dependencies: "@fortawesome/fontawesome-free" "^5.14.0" FileSaver "^0.10.0"
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor