@@ -234,6 +234,13 @@ def handle_retrieval_request(self, request: RetrievalRequest) -> RetrievalRespon
234
234
RETRIEVAL_FILE_PATH = os .getenv ("RETRIEVAL_FILE_PATH" , default = "./retrieval_docs" )+ '/'
235
235
EXCEPT_PATTERNS = ["/xuhui_doc" , "default/persist_dir" ]
236
236
237
+ def safe_join (base_path , * paths ):
238
+ # Prevent path traversal by ensuring the final path is within the base path
239
+ base_path = os .path .abspath (base_path )
240
+ final_path = os .path .abspath (os .path .join (base_path , * paths ))
241
+ if not final_path .startswith (base_path ):
242
+ raise ValueError ("Attempted Path Traversal Detected" )
243
+ return final_path
237
244
238
245
@router .post ("/v1/askdoc/upload_link" )
239
246
async def retrieval_upload_link (request : Request ):
@@ -316,7 +323,7 @@ async def retrieval_add_files(request: Request,
316
323
path_prefix = get_path_prefix (kb_id , user_id )
317
324
upload_path = path_prefix + '/upload_dir'
318
325
persist_path = path_prefix + '/persist_dir'
319
- save_path = Path (upload_path ) / file_path
326
+ save_path = safe_join ( Path (upload_path ), file_path )
320
327
save_path .parent .mkdir (parents = True , exist_ok = True )
321
328
322
329
# save file content to local disk
@@ -618,7 +625,7 @@ async def delete_single_file(request: Request):
618
625
logger .info (f"[askdoc - delete_file] successfully delete kb { knowledge_base_id } " )
619
626
return {"status" : True }
620
627
621
- delete_path = Path (path_prefix ) / "upload_dir" / del_path
628
+ delete_path = safe_join ( Path (path_prefix ) / "upload_dir" , del_path )
622
629
logger .info (f'[askdoc - delete_file] delete_path: { delete_path } ' )
623
630
624
631
# partially delete files/folders from the kb
0 commit comments