file_manager: Verify that uploads are not written to folders outside of the "base" directory

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Arksine 2020-07-23 07:32:29 -04:00 committed by Eric Callahan
parent 9743772b45
commit 8b5c8786b4
1 changed files with 9 additions and 5 deletions

View File

@ -299,8 +299,8 @@ class FileManager:
# lookup root file path # lookup root file path
root_args = request.arguments.get('root', ['gcodes']) root_args = request.arguments.get('root', ['gcodes'])
root = root_args[0].strip() root = root_args[0].strip()
file_path = self.file_paths.get(root, None) base_path = self.file_paths.get(root, None)
if file_path is None: if base_path is None:
raise self.server.error(400, "Unknown root path") raise self.server.error(400, "Unknown root path")
# check relative path # check relative path
path_args = request.arguments.get('path', []) path_args = request.arguments.get('path', [])
@ -320,17 +320,21 @@ class FileManager:
raise self.server.error( raise self.server.error(
400, "Bad Request, can only process a single file upload") 400, "Bad Request, can only process a single file upload")
upload = f_list[0] upload = f_list[0]
if os.path.isfile(file_path): if os.path.isfile(base_path):
# If the root path points to a file, write directly to it. This # If the root path points to a file, write directly to it. This
# is the case for printer.cfg # is the case for printer.cfg
filename = root filename = root
full_path = file_path full_path = base_path
dir_path = "" dir_path = ""
else: else:
filename = "_".join(upload['filename'].strip().split()).lstrip("/") filename = "_".join(upload['filename'].strip().split()).lstrip("/")
if dir_path: if dir_path:
filename = os.path.join(dir_path, filename) filename = os.path.join(dir_path, filename)
full_path = os.path.join(file_path, filename) full_path = os.path.normpath(os.path.join(base_path, filename))
# Validate the path. Don't allow uploads to a parent of the root
if not full_path.startswith(base_path):
raise self.server.error(
"Cannot write to path: %s" % (full_path))
# Verify that the operation can be done if attempting to upload a gcode # Verify that the operation can be done if attempting to upload a gcode
if root == 'gcodes': if root == 'gcodes':
try: try: