From 0f64b3e85a6a0fa0c056454b021960a004af390c Mon Sep 17 00:00:00 2001 From: Malik Bougacha Date: Thu, 3 Sep 2020 10:58:05 +0200 Subject: [PATCH] Address directory transversal. remove two potential directory transversal change the custom check for this exploit for the flask safe_join --- api/app/api_v1/computation_module.py | 5 +++-- api/app/api_v1/users.py | 4 +++- api/app/model.py | 15 +++++---------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/api/app/api_v1/computation_module.py b/api/app/api_v1/computation_module.py index 2f0e47ce..d7068d0a 100644 --- a/api/app/api_v1/computation_module.py +++ b/api/app/api_v1/computation_module.py @@ -26,6 +26,7 @@ import os import json +import flask from flask import send_from_directory, send_file from app.constants import UPLOAD_DIRECTORY, DATASET_DIRECTORY @@ -97,7 +98,7 @@ def get(self,filename): @ns.route('/tiles/////', methods=['GET']) class getRasterTile(Resource): - def get(self,directory,z,x,y): + def get(self,directory, z, x, y): """ download a file from the main web service :return: @@ -122,7 +123,7 @@ def registerCM(input): def savefile(filename,url): r = requests.get(url, stream=True) if r.status_code == 200: - path = os.path.join(UPLOAD_DIRECTORY, filename) + path = (UPLOAD_DIRECTORY, filename) with open(path, 'wb') as f: for chunk in r.iter_content(1024): f.write(chunk) diff --git a/api/app/api_v1/users.py b/api/app/api_v1/users.py index dba82b89..45597d4e 100644 --- a/api/app/api_v1/users.py +++ b/api/app/api_v1/users.py @@ -2,6 +2,7 @@ import os import uuid +import flask from flask_mail import Message from flask_restplus import Resource from flask_security import SQLAlchemySessionUserDatastore @@ -584,7 +585,8 @@ def post(self): if 'file' in args and args['file'] is not None: file=args['file'] - file_upload_path = os.path.join(constants.USER_UPLOAD_FOLDER, str(uuid.uuid4())+'_'+file.filename) + filename = str(uuid.uuid4())+'_'+file.filename + file_upload_path = flask.safe_join(constants.USER_UPLOAD_FOLDER, filename) file.save(file_upload_path) with open(file_upload_path, 'rb') as f: msg.attach(file.filename, "image/*", f.read()) diff --git a/api/app/model.py b/api/app/model.py index b45f5e95..a7573048 100644 --- a/api/app/model.py +++ b/api/app/model.py @@ -12,6 +12,7 @@ except ImportError: from pipes import quote import subprocess +import flask from app.constants import DATASET_DIRECTORY, USER_DB,HOST_DB,PASSWORD_DB,PORT_DB,DATABASE_DB from app.constants import DATASET_DIRECTORY, UPLOAD_DIRECTORY, NUTS_YEAR, LAU_YEAR from datetime import datetime @@ -330,12 +331,9 @@ def get_raster_from_csv(wkt_point, layer_needed, output_directory): type = layer['name'] id = 0 if id == 0: - dataset_directory = DATASET_DIRECTORY directory = layer['workspaceName'] - root_path = dataset_directory + directory + "/data/" - path_to_dataset = root_path + layer['workspaceName'] + ".tif" - if not os.path.abspath(path_to_dataset).startswith(root_path): - raise Exception("directory traversal denied") + filename = layer['workspaceName'] + ".tif" + path_to_dataset = flask.safe_join(DATASET_DIRECTORY, directory, 'data', filename) else: upload = Uploads.query.get(layer['id']) path_to_dataset = upload.url @@ -367,12 +365,9 @@ def clip_raster_from_shapefile(shapefile_path,layer_needed, output_directory): type = layer['name'] id = 0 if id == 0: - dataset_directory = DATASET_DIRECTORY directory = layer['workspaceName'] - root_path = dataset_directory + directory + "/data/" - path_to_dataset = root_path + layer['workspaceName'] + ".tif" - if not os.path.abspath(path_to_dataset).startswith(root_path): - raise Exception("directory traversal denied") + filename = layer['workspaceName'] + ".tif" + path_to_dataset = flask.safe_join(DATASET_DIRECTORY, directory, 'data', filename) else: upload = Uploads.query.filter_by(id=layer['id']).first() path_to_dataset = upload.url