Server-side Request Forgery (SSRF) Affecting mindsdb package, versions [,23.12.4.2)


Severity

Recommended
0.0
high
0
10

CVSS assessment made by Snyk's Security Team

    Threat Intelligence

    Exploit Maturity
    Proof of concept
    EPSS
    0.08% (37th percentile)

Do your applications use this vulnerable package?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications
  • Snyk ID SNYK-PYTHON-MINDSDB-7919087
  • published 6 Sep 2024
  • disclosed 5 Sep 2024
  • credit Sim4n6

How to fix?

Upgrade MindsDB to version 23.12.4.2 or higher.

Overview

MindsDB is a MindsDB server, provides server capabilities to mindsdb native python library

Affected versions of this package are vulnerable to Server-side Request Forgery (SSRF) through the is_private_url function. An attacker can manipulate DNS responses to redirect traffic to malicious sites or local IP addresses by exploiting the DNS rebinding technique.

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)

References

CVSS Scores

version 4.0
version 3.1
Expand this section

Snyk

Recommended
7.8 high
  • Attack Vector (AV)
    Network
  • Attack Complexity (AC)
    Low
  • Attack Requirements (AT)
    None
  • Privileges Required (PR)
    None
  • User Interaction (UI)
    None
  • Confidentiality (VC)
    None
  • Integrity (VI)
    None
  • Availability (VA)
    None
  • Confidentiality (SC)
    High
  • Integrity (SI)
    None
  • Availability (SA)
    Low