diff --git a/lollms/binding.py b/lollms/binding.py index 5a8981b..1a6c46c 100644 --- a/lollms/binding.py +++ b/lollms/binding.py @@ -164,7 +164,7 @@ class LLMBinding: def reference_model(self, path): path = str(path).replace("\\","/") model_name = path.split("/")[-1]+".reference" - folder_path = self.searchModelPath(model_name).replace(".reference","") + folder_path = Path(str(self.searchModelPath(model_name)).replace(".reference","")) model_full_path = (folder_path / model_name) # Check if file already exists in folder @@ -617,7 +617,7 @@ class LLMBinding: model_path = self.models_folders[0] return model_path - + """ def searchModelPath(self, model_name:str): model_path=None for mn in self.models_folders: @@ -628,7 +628,7 @@ class LLMBinding: model_path = self.models_folders[0]/model_name return model_path - + """ def get_model_path(self): """ Retrieves the path of the model based on the configuration. diff --git a/lollms/security.py b/lollms/security.py index 45086c6..64b4110 100644 --- a/lollms/security.py +++ b/lollms/security.py @@ -1,9 +1,10 @@ from fastapi import HTTPException from ascii_colors import ASCIIColors from pathlib import Path +from typing import List +import os - -def sanitize_path(path:str, allow_absolute_path:False, error_text="Absolute database path detected", exception_text="Detected an attempt of path traversal. Are you kidding me?"): +def sanitize_path(path:str, allow_absolute_path:bool=False, error_text="Absolute database path detected", exception_text="Detected an attempt of path traversal. Are you kidding me?"): if(".." in path): ASCIIColors.warning(error_text) raise exception_text @@ -20,3 +21,19 @@ def forbid_remote_access(lollmsElfServer): if lollmsElfServer.config.host!="localhost" and lollmsElfServer.config.host!="127.0.0.1": return {"status":False,"error":"Code execution is blocked when the server is exposed outside for very obvious reasons!"} + +def validate_path(path, allowed_paths:List[str|Path]): + # Convert the path to an absolute path + abs_path = os.path.realpath(str(path)) + + # Iterate over the allowed paths + for allowed_path in allowed_paths: + # Convert the allowed path to an absolute path + abs_allowed_path = os.path.realpath(allowed_path) + + # Check if the absolute path starts with the absolute allowed path + if abs_path.startswith(abs_allowed_path): + return True + + # If the path is not within any of the allowed paths, return False + return False diff --git a/lollms/server/endpoints/lollms_xtts.py b/lollms/server/endpoints/lollms_xtts.py index 1036bc5..aba1745 100644 --- a/lollms/server/endpoints/lollms_xtts.py +++ b/lollms/server/endpoints/lollms_xtts.py @@ -14,6 +14,7 @@ from starlette.responses import StreamingResponse from lollms.types import MSG_TYPE from lollms.main_config import BaseConfig from lollms.utilities import detect_antiprompt, remove_text_from_string, trace_exception, find_first_available_file_index, add_period, PackageManager +from lollms.security import sanitize_path, validate_path from pathlib import Path from ascii_colors import ASCIIColors import os @@ -86,6 +87,10 @@ async def text2Audio(request: LollmsText2AudioRequest): if lollmsElfServer.config.host!="localhost" and lollmsElfServer.config.host!="127.0.0.1": return {"status":False,"error":"Code execution is blocked when the server is exposed outside for very obvious reasons!"} + if request.fn: + request.fn = os.path.realpath(str((lollmsElfServer.lollms_paths.personal_outputs_path/"audio_out")/request.fn)) + validate_path(request.fn,[str(lollmsElfServer.lollms_paths.personal_outputs_path/"audio_out")]) + try: # Get the JSON data from the POST request. try: