Feb 25, 2026·6 min read·5 visits
MindsDB trusted user-supplied filenames in its upload handler. Attackers can use directory traversal ('../') to overwrite files anywhere on the server. Overwriting a common library like 'pip' and triggering an install process grants full RCE.
A critical path traversal vulnerability in MindsDB allows authenticated attackers to break out of the upload sandbox and overwrite arbitrary system files. By manipulating the 'Content-Disposition' header during file uploads, an attacker can replace core Python libraries with malicious code, leading to Remote Code Execution (RCE) when the application subsequently attempts to use those libraries. The flaw stems from an unsafe configuration of the 'python-multipart' library.
MindsDB is a darling of the AI world, bridging the gap between traditional SQL databases and machine learning models. It essentially allows you to query predictive models as if they were database tables. It’s a complex beast, often deployed on high-powered GPU instances that are juicy targets for crypto-miners and corporate spies alike.
Like any modern data platform, it needs a way to ingest data. Enter the /api/files endpoint. This is the front door for users to upload their CSVs, JSONs, and datasets to train their models. Usually, file uploads are handled with kid gloves: generated UUID filenames, sandboxed directories, and strict validation.
But in CVE-2026-27483, MindsDB didn't just drop the ball; they threw it through their own window. By trusting the filename provided by the client, they turned a simple file upload feature into a primitive filesystem editor. If you can write a file anywhere, you can run code anywhere.
The root cause here is a classic case of "Default Insecurity" combined with developer oversight. MindsDB uses python-multipart to parse incoming HTTP multipart requests. This library is generally robust, but it offers a configuration option that is practically a foot-gun if you aren't careful: UPLOAD_KEEP_FILENAME.
Prior to version 25.9.1.1, MindsDB explicitly set this option to True. Here is the logic flaw in plain English: The application told the library, "Hey, whatever filename the user sends in the HTTP headers, please respect that and use it on our disk."
> [!WARNING]
> trusting Content-Disposition is fatal. Attackers control the HTTP request headers entirely.
When a standard user uploads data.csv, everything is fine. But when a hacker uploads a file and sets the filename to ../../../../bin/evil.sh, the library—following its configuration—dutifully traverses up the directory tree and plants the file outside the intended temporary folder. There was zero sanitization of path separators (/ or \) before the write operation occurred.
Let's look at the patch, which is effectively a confession of the crime. The fix was applied in commit 87a44bdb2b97f963e18f10a068e1a1e2690505ef. The developers had to do two things: stop the library from being so helpful, and verify the input themselves.
Here is the critical diff from mindsdb/api/http/namespaces/file.py. Notice the addition of the pathlib check and the configuration flip:
# THE FIX
- data["file"] = file.file_name.decode()
+ file_name = file.file_name.decode()
+ data["file"] = file_name
+ # 1. Validate the filename has no path info
+ if Path(file_name).name != file_name:
+ raise ValueError(f"Wrong file name: {file_name}")
# ... later in the file ...
- "UPLOAD_KEEP_FILENAME": True,
+ # 2. Stop the library from using the input filename
+ "UPLOAD_KEEP_FILENAME": False,The check Path(file_name).name != file_name is simple but effective. If file_name is foo.csv, Path('foo.csv').name is foo.csv. They match. If file_name is ../foo.csv, Path('../foo.csv').name is just foo.csv. They don't match, and the exception is raised.
So we can write files anywhere. How do we turn that into a shell? We could try to overwrite /etc/passwd, but we might not have root. A more elegant approach targets the application's own dependencies. MindsDB is a Python application, and Python is very trusting of its environment.
The research indicates that MindsDB exposes an /install endpoint that triggers pip via a subprocess to install integrations. This is our trigger mechanism. If we can overwrite a file that pip (or the installation process) loads, we win.
The Attack Chain:
site-packages directory. Since we have low-privilege access, we likely can't write to system folders, but we can overwrite files inside the MindsDB environment or user-local packages.POST request to /api/files with a filename like ../../../../usr/local/lib/python3.10/site-packages/pip/__init__.py./install endpoint. The server spins up a subprocess, imports pip (which is now our malicious file), and executes our code.This is an 8.8 CVSS for a reason. While it requires authentication, in many enterprise environments, "authentication" just means having a valid SSO token or being an internal user. The impact is effectively total system compromise.
Once an attacker has RCE on a MindsDB instance, they have access to:
The vulnerability is particularly dangerous because it leaves very few artifacts if the attacker cleans up after themselves. They overwrite a library, execute the payload, and then overwrite the library back with the original content.
If you are running MindsDB, stop reading and upgrade to 25.9.1.1 immediately. The patch is relatively simple, but it closes the hole completely by forcing random temporary filenames and validating input.
For Developers:
Content-Disposition. Treat filenames as user input, because they are. Sanitize them aggressively.quarterly_report.csv. Save it as 550e8400-e29b-41d4-a716-446655440000.csv and store the mapping to the real name in your database.python-multipart. The patch included an upgrade to 0.0.20.If upgrading is impossible (why?), you can mitigate this at the WAF level by blocking requests to /api/files that contain .. or %2e%2e in the body payload, though this is notoriously difficult to do correctly with multipart data.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
MindsDB MindsDB | < 25.9.1.1 | 25.9.1.1 |
| Attribute | Detail |
|---|---|
| CWE | CWE-22 (Path Traversal) |
| CVSS | 8.8 (Critical) |
| Attack Vector | Network (Authenticated) |
| Impact | Remote Code Execution (RCE) |
| Library | python-multipart |
| Fix Commit | 87a44bd |
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')