From 11d4f39cab2a7de333aeb4a8f0d1feedd58b4d30 Mon Sep 17 00:00:00 2001 From: Christian Boettcher <c.boettcher@fz-juelich.de> Date: Tue, 22 Jun 2021 14:41:15 +0200 Subject: [PATCH] add verification of oid format --- apiserver/main.py | 8 +++++++- apiserver/storage/JsonFileStorageAdapter.py | 11 +++++++++++ apiserver/storage/__init__.py | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/apiserver/main.py b/apiserver/main.py index fcfbeb6..f527e4b 100644 --- a/apiserver/main.py +++ b/apiserver/main.py @@ -15,7 +15,7 @@ from .config import ApiserverSettings from .security import (ACCESS_TOKEN_EXPIRES_MINUTES, JsonDBInterface, Token, User, authenticate_user, create_access_token, get_current_user) -from .storage import JsonFileStorageAdapter, LocationData, LocationDataType +from .storage import JsonFileStorageAdapter, LocationData, LocationDataType, verify_oid class ReservedPaths(str, Enum): @@ -86,6 +86,8 @@ async def list_datasets(location_data_type: LocationDataType): @app.get("/{location_data_type}/{dataset_id}", response_model=LocationData) async def get_specific_dataset(location_data_type: LocationDataType, dataset_id: str): """returns all information about a specific dataset, identified by id""" + if not verify_oid(dataset_id): + raise HTTPException(status_code=400, detail="Invalid OID format!") return adapter.get_details(location_data_type, dataset_id) @app.post("/{location_data_type}") @@ -101,6 +103,8 @@ async def update_specific_dataset(location_data_type: LocationDataType, dataset_id: str, dataset: LocationData, user: User = Depends(my_user)): """update the information about a specific dataset, identified by id""" + if not verify_oid(dataset_id): + raise HTTPException(status_code=400, detail="Invalid OID format!") return adapter.update_details(location_data_type, dataset_id, dataset, user.username) @@ -109,6 +113,8 @@ async def delete_specific_dataset(location_data_type: LocationDataType, dataset_id: str, user: str = Depends(my_user)): """delete a specific dataset""" + if not verify_oid(dataset_id): + raise HTTPException(status_code=400, detail="Invalid OID format!") # TODO: 404 is the right answer? 204 could also be the right one return adapter.delete(location_data_type, dataset_id, user.username) diff --git a/apiserver/storage/JsonFileStorageAdapter.py b/apiserver/storage/JsonFileStorageAdapter.py index 4510694..b2197a2 100644 --- a/apiserver/storage/JsonFileStorageAdapter.py +++ b/apiserver/storage/JsonFileStorageAdapter.py @@ -24,6 +24,17 @@ def get_unique_id(path: str) -> str: oid = str(uuid.uuid4()) return oid + +def verify_oid(oid: str, version=4): + """ Ensure thatthe oid is formatted as a valid oid (i.e. UUID v4). + If it isn't, the corresponding request could theoretically be an attempted path traversal attack (or a regular typo). + """ + try: + uuid_obj = uuid.UUID(oid, version=version) + except: + return False + return str(uuid_obj) == oid + class JsonFileStorageAdapter(AbstractLocationDataStorageAdapter): """ This stores LocationData via the StoredData Object as json files diff --git a/apiserver/storage/__init__.py b/apiserver/storage/__init__.py index 3d63565..8c48a89 100644 --- a/apiserver/storage/__init__.py +++ b/apiserver/storage/__init__.py @@ -1,3 +1,3 @@ -from .JsonFileStorageAdapter import JsonFileStorageAdapter +from .JsonFileStorageAdapter import JsonFileStorageAdapter, verify_oid from .LocationStorage import LocationDataType, LocationData, AbstractLocationDataStorageAdapter \ No newline at end of file -- GitLab