CVE-2024-1520: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') (CWE-78)
value: An OS Command Injection vulnerability exists in the '/open_code_folder' endpoint of the parisneo/lollms-webui application, due to improper validation of user-supplied input in the 'discussion_id' parameter. Attackers can exploit this vulnerability by injecting malicious OS commands, leading to unauthorized command execution on the underlying operating system. This could result in unauthorized access, data leakage, or complete system compromise.
CWE description: The product constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component.
Published: 2024-04-10T17:15Z
Repository: https://github.com/parisneo/lollms-webui
Language: Python
Files changed: endpoints/lollms_advanced.py
Commit date: 2024-02-15 09:19:47 +0100
Commit message: Update lollms_advanced.py
Diff: diff --git a/endpoints/lollms_advanced.py b/endpoints/lollms_advanced.py
index a3fdb18..74ccbab 100644
--- a/endpoints/lollms_advanced.py
+++ b/endpoints/lollms_advanced.py
@@ -199,11 +199,11 @@ async def open_file(file_path: FilePath):
         
         # Sanitize the 'path' parameter
         path = os.path.realpath(path)
         
         # Use subprocess.Popen to safely open the file
-        subprocess.Popen(["start", path], shell=True)
+        subprocess.Popen(["start", path])
         
         return {"status": True, "execution_time": 0}
     
     except Exception as ex:
         trace_exception(ex)
@@ -236,11 +236,11 @@ async def open_code_in_vs_code(vs_code_data: VSCodeData):
         tmp_file = root_folder/f"ai_code_{message_id}.py"
         with open(tmp_file,"w") as f:
             f.write(code)
         
         # Use subprocess.Popen to safely open the file
-        subprocess.Popen(["code", str(root_folder)], shell=True)
+        subprocess.Popen(["code", str(root_folder)])
         
         return {"status": True, "execution_time": 0}
     except Exception as ex:
         trace_exception(ex)
         lollmsElfServer.error(ex)
@@ -266,11 +266,11 @@ async def open_code_folder(request: FolderRequest):
             ASCIIColors.info("Opening folder:")
             # Create a temporary file.
             root_folder = lollmsElfServer.lollms_paths.personal_outputs_path / "discussions" / f"d_{discussion_id}"
             root_folder.mkdir(parents=True, exist_ok=True)
             if platform.system() == 'Windows':
-                subprocess.run(['start', str(root_folder)], check=True, shell=True)
+                subprocess.run(['start', str(root_folder)], check=True)
             elif platform.system() == 'Linux':
                 subprocess.run(['xdg-open', str(root_folder)], check=True)
             elif platform.system() == 'Darwin':
                 subprocess.run(['open', str(root_folder)], check=True)
             return {"status": True, "execution_time": 0}
@@ -285,11 +285,11 @@ async def open_code_folder(request: FolderRequest):
 
             ASCIIColors.info("Opening folder:")
             # Create a temporary file.
             root_folder.mkdir(parents=True, exist_ok=True)
             if platform.system() == 'Windows':
-                subprocess.run(['start', str(root_folder)], check=True, shell=True)
+                subprocess.run(['start', str(root_folder)], check=True)
             elif platform.system() == 'Linux':
                 subprocess.run(['xdg-open', str(root_folder)], check=True)
             elif platform.system() == 'Darwin':
                 subprocess.run(['open', str(root_folder)], check=True)
             return {"status": True, "execution_time": 0}

Vulnerable code:         subprocess.Popen(["start", path], shell=True)
        subprocess.Popen(["code", str(root_folder)], shell=True)
                subprocess.run(['start', str(root_folder)], check=True, shell=True)
                subprocess.run(['start', str(root_folder)], check=True, shell=True)
Fixed code:         subprocess.Popen(["start", path])
        subprocess.Popen(["code", str(root_folder)])
                subprocess.run(['start', str(root_folder)], check=True)
                subprocess.run(['start', str(root_folder)], check=True)