From 5eb706767c985a2edfea9852f934a10526e6f877 Mon Sep 17 00:00:00 2001 From: jrybicki-jsc <j.rybicki@fz-juelich.de> Date: Tue, 8 Jun 2021 13:56:38 +0200 Subject: [PATCH] first steps against path traversal --- apiserver/storage/JsonFileStorageAdapter.py | 13 +++++++++---- tests/apiserver_tests/test_put.py | 12 ------------ tests/storage_tests/test_jsonbackend.py | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 16 deletions(-) delete mode 100644 tests/apiserver_tests/test_put.py diff --git a/apiserver/storage/JsonFileStorageAdapter.py b/apiserver/storage/JsonFileStorageAdapter.py index bdae20d..4510694 100644 --- a/apiserver/storage/JsonFileStorageAdapter.py +++ b/apiserver/storage/JsonFileStorageAdapter.py @@ -50,11 +50,16 @@ class JsonFileStorageAdapter(AbstractLocationDataStorageAdapter): def __get_object_path(self, value: str, oid: str) -> str: localpath = os.path.join(self.data_dir, value) - fullpath = os.path.join(localpath, oid) - if not os.path.isfile(fullpath): + full_path = os.path.join(localpath, oid) + common = os.path.commonprefix((os.path.realpath(full_path),os.path.realpath(self.data_dir))) + if common != os.path.realpath(self.data_dir): + print(f"Escaping the data dir! {common} {full_path}") + raise FileNotFoundError() + + if not os.path.isfile(full_path): raise FileNotFoundError( - f"The requested object ({oid}) does not exist.") - return fullpath + f"The requested object ({oid}) {full_path} does not exist.") + return full_path def get_list(self, n_type: LocationDataType) -> List: local_path = self.__setup_path(n_type.value) diff --git a/tests/apiserver_tests/test_put.py b/tests/apiserver_tests/test_put.py deleted file mode 100644 index 3c435a8..0000000 --- a/tests/apiserver_tests/test_put.py +++ /dev/null @@ -1,12 +0,0 @@ -# These Tests check if the PUT calls work as intended, checking both valid puts and invalid puts - -from fastapi.testclient import TestClient - -from context import apiserver -from context import storage - -client = TestClient(apiserver.app) - -# PUT a new dataset, store the id in global variable, verify via a GET if it worked - -# PUT an invalid type (i.e. a type not in the enum) diff --git a/tests/storage_tests/test_jsonbackend.py b/tests/storage_tests/test_jsonbackend.py index 5dada28..f977080 100644 --- a/tests/storage_tests/test_jsonbackend.py +++ b/tests/storage_tests/test_jsonbackend.py @@ -6,6 +6,7 @@ from collections import namedtuple import os import pathlib import shutil +import json class SomeTests(unittest.TestCase): @@ -81,3 +82,21 @@ class SomeTests(unittest.TestCase): data=new_data, usr='tst2') self.assertEqual(new_data, r) self.assertEqual(oid, oid2) + + + def test_path_traversal(self): + l_data = LocationData(name='test1', url='http://n.go', metadata=[]) + + with open('/tmp/hackme', 'w+') as f: + json.dump({'secret': 'data', 'users': [], 'actualData': {'name': 'some', 'url': 'oo'}}, f) + + (oid, data) = self.store.add_new(n_type=LocationDataType.DATASET, data=l_data, user_name='test_user') + details = None + try: + details = self.store.get_details(n_type=LocationDataType.DATASET, oid='../../../tmp/hackme') + except: + pass + print(details) + self.assertIsNone(details) + + -- GitLab