Back to Intelligence

CVE-2026-77933: DB-GPT Ships Hardcoded MySQL Root Credentials — Detection and Remediation Guide

SA
Security Arsenal Team
October 20, 2026
13 min read

NVD has published CVE-2026-77933, a CVSS 9.8 (Critical) vulnerability affecting DB-GPT through version 0.8.2 — the popular open-source AI-native data application framework that many organizations have quietly deployed to bridge large language models with internal databases. The flaw is embarrassingly simple and devastatingly effective: DB-GPT's default docker-compose.yml ships with a hardcoded MYSQL_ROOT_PASSWORD and publishes MySQL port 3306 on all interfaces (0.0.0.0). Any attacker who can reach that port — from the internet, from a compromised host on the LAN, or from another container on the shared dbgptnet Docker network — can authenticate as root@% and walk away with full database access, including FILE and SUPER privileges.

Let me be blunt about what FILE privilege means in practice: SELECT ... INTO OUTFILE and LOAD DATA LOCAL INFILE are the classic stepping stones to arbitrary file read/write on the underlying host, and from there, code execution is a short hop (webshells via UDF library loading, writing cron entries or SSH keys where filesystem permissions allow). This is not a theoretical configuration nit. It is a pre-authenticated, network-reachable, credentials-in-plaintext backdoor in a component that is, by design, connected to your most sensitive data sources. If you stood up DB-GPT with the default compose file for a "quick PoC" of AI-powered analytics, that instance is one port scan away from full compromise.

Technical Analysis

Affected Products and Versions

AttributeDetail
CVECVE-2026-77933
CVSS v3.x9.8 (Critical) — vector pathway: NETWORK
Affected productDB-GPT through 0.8.2 (all versions ≤ 0.8.2)
Vulnerable artifactDefault docker-compose.yml shipped with the project
Affected componentBundled MySQL service (dbgptnet Docker network)
Weakness classCWE-798 (Use of Hard-coded Credentials) + CWE-668 (Exposure of Resource to Wrong Sphere)
Exploitation requirementsNetwork reachability to TCP/3306 or membership in the dbgptnet bridge network

Reference: NVD — CVE-2026-77933

How the Vulnerability Works (Defender's View)

The attack chain is trivial, which is precisely why the CVSS score is maxed out:

  1. Deployment: An operator clones the DB-GPT repository and runs docker compose up using the shipped docker-compose.yml. The MySQL service is defined with a static MYSQL_ROOT_PASSWORD value baked into the file, and the port mapping 3306:3306 is bound to all host interfaces rather than 127.0.0.1.

  2. Exposure: Because the bind is 0.0.0.0:3306, the database is reachable from any network interface on the host — including public interfaces if the host is a cloud VM without a restrictive security group. Even when the host is behind a firewall, any other container attached to the shared dbgptnet bridge network can reach MySQL directly. A single compromised web container in the same compose stack becomes a pivot straight into the database.

  3. Authentication: The root account is configured as root@%, meaning the hardcoded password is accepted from any source host — not just localhost. The attacker runs mysql -h <target> -u root -p<known-password> and is in.

  4. Impact: With root@% holding SUPER and FILE privileges, the attacker can:

    • Dump, modify, or destroy all databases — including any business data DB-GPT was granted access to.
    • Read host files via LOAD DATA LOCAL INFILE / LOAD_FILE() (subject to secure_file_priv and filesystem permissions).
    • Write files to the host via SELECT ... INTO OUTFILE — the standard path to webshells, UDF-based privilege escalation (lib_mysqludf_sys-style), or dropping SSH keys/cron entries when the container is run with elevated mounts.
    • Enumerate DB-GPT's configured downstream data sources — connection strings to production databases, API keys, LLM provider tokens stored in application tables.

The last point deserves emphasis: DB-GPT's entire purpose is to hold credentials and connection strings to other data systems. Compromising its backing MySQL instance is not just a database breach — it is a credential harvesting platform pointed at everything DB-GPT was trusted to touch.

Exploitation Status

As of publication, CVE-2026-77933 has been published by NVD with a full technical description that effectively functions as an exploitation recipe — the "PoC" is a one-line mysql client command against an internet-indexable port. Databases exposed on 3306 are among the most aggressively scanned services on the internet; shodan-indexed MySQL instances are typically probed within minutes of exposure. While CISA KEV inclusion has not been confirmed at the time of writing, defenders should treat this as trivially exploitable at scale and assume any internet-exposed instance has already been probed. Do not wait for confirmation of in-the-wild exploitation to act.

Detection & Response

This is a technical threat, so the sections below provide detection content your SOC can deploy today. The core detection philosophy: the vulnerability is a configuration flaw, so the highest-fidelity detections are (a) finding exposed MySQL listeners, and (b) catching anomalous authentication and abuse of FILE/SUPER privileges.

Sigma Rules

The first rule targets abuse of the MySQL FILE privilege — file-write primitives that indicate post-exploitation. The second targets suspicious remote MySQL authentication visible in syslog/auth telemetry on the database host.

YAML
---
title: MySQL FILE Privilege Abuse — INTO OUTFILE / DUMPFILE / LOAD DATA
description: Detects MySQL SQL statements abusing FILE privilege (INTO OUTFILE, INTO DUMPFILE, LOAD DATA) consistent with post-exploitation of CVE-2026-77933-style hardcoded credential access, enabling arbitrary file read/write on the host.
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-77933
  - https://attack.mitre.org/techniques/T1505/
author: Security Arsenal
date: 2026/04/06
status: experimental
id: 9c2e7b41-3f6a-4d58-b1e2-7a0d4c8f5b19
tags:
  - attack.persistence
  - attack.t1505.003
  - attack.t1005
logsource:
  category: application
  product: mysql
detection:
  selection:
    query|contains:
      - 'INTO OUTFILE'
      - 'INTO DUMPFILE'
      - 'LOAD DATA'
      - 'LOAD_FILE('
  filter_localhost:
    user|contains: 'root@localhost'
  condition: selection and not filter_localhost
falsepositives:
  - Legitimate ETL jobs and backup scripts using LOAD DATA or INTO OUTFILE from application accounts
level: high
---
title: Remote MySQL Root Authentication From Non-Localhost Source
description: Detects successful MySQL root logins originating from non-localhost sources, consistent with exploitation of hardcoded root@% credentials as described in CVE-2026-77933 (DB-GPT default docker-compose exposure).
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-77933
  - https://attack.mitre.org/techniques/T1078/
author: Security Arsenal
date: 2026/04/06
status: experimental
id: 4b8d1e62-7c3a-4f09-a5d1-2e6c9b3f7d40
tags:
  - attack.initial_access
  - attack.t1078
  - attack.t1190
logsource:
  product: linux
  service: mysql
detection:
  selection:
    message|contains:
      - 'Access granted'
      - 'Access denied'
    message|contains_all:
      - 'root'
      - '@'
  filter_local:
    message|contains:
      - 'root@localhost'
      - 'root@127.0.0.1'
  condition: selection and not filter_local
falsepositives:
  - Legitimate remote DBA access (should be eliminated regardless — root@% is never acceptable)
level: high

Note: MySQL query/audit logging must be enabled (general query log, or the MySQL Enterprise Audit / MariaDB audit plugin) for rule one to have telemetry. If your MySQL containers log to stdout, ensure your log pipeline ingests container logs.

KQL (Microsoft Sentinel / Defender)

This query hunts for network connections to MySQL (3306) from unexpected sources — both via Syslog/CEF-ingested firewall and container telemetry, and via Defender endpoint network events. Tune the allowed source list to your known application subnets.

KQL — Microsoft Sentinel / Defender
// Hunt: Unexpected inbound connections to MySQL 3306 (CVE-2026-77933 exposure)
let Lookback = 7d;
let AllowedSources = dynamic(["10.10.0.0/16", "172.18.0.0/16"]); // TODO: replace with your approved app-tier CIDRs
union isfuzzy=true
( CommonSecurityLog
  | where TimeGenerated > ago(Lookback)
  | where DestinationPort == 3306
  | project TimeGenerated, SourceIP, DestinationIP, DestinationPort, DeviceAction, Protocol=_Protocol
),
( DeviceNetworkEvents
  | where TimeGenerated > ago(Lookback)
  | where RemotePort == 3306 and ActionType == "ConnectionSuccess"
  | project TimeGenerated, SourceIP=LocalIP, DestinationIP=RemoteIP, DestinationPort=RemotePort, DeviceAction=ActionType, InitiatingProcessFileName
);
// Enrichment: flag connections NOT from approved subnets
// Also hunt for mysql client execution on hosts that should never run it:
DeviceProcessEvents
| where TimeGenerated > ago(Lookback)
| where FileName in~ ("mysql", "mysql.exe", "mariadb", "mycli")
| where ProcessCommandLine has_any ("-h", "--host")
| where ProcessCommandLine !has "localhost" and ProcessCommandLine !has "127.0.0.1"
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName
| order by TimeGenerated desc

The second half of the hunt looks for interactive MySQL client usage targeting remote hosts — on most servers, there is no legitimate reason for an ad-hoc mysql -h session. In environments where DBAs do this routinely, scope the query to your DB-GPT hosts and container hosts specifically.

Velociraptor VQL

This artifact enumerates listening sockets and live connections on Linux hosts to identify MySQL exposed on non-loopback interfaces, and surfaces processes matching MySQL/mysqld — useful for a fleet-wide sweep for rogue DB-GPT deployments your asset inventory doesn't know about (shadow AI tooling is the realistic exposure here).

VQL — Velociraptor
-- CVE-2026-77933 hunt: find MySQL listeners bound to non-loopback interfaces
-- and active 3306 connections across the fleet.
SELECT Pid,
       Name,
       Exe,
       Address.Local AS LocalAddress,
       Address.LocalPort AS LocalPort,
       Address.Remote AS RemoteAddress,
       Address.RemotePort AS RemotePort,
       Address.State AS State
FROM netstat()
WHERE LocalPort == 3306
   OR RemotePort == 3306

-- Also enumerate mysql/mysqld processes to identify unmanaged DB-GPT containers
SELECT Pid,
       Name,
       CommandLine,
       Exe,
       Username,
       CreateTime
FROM pslist()
WHERE Name =~ 'mysql|mariadb'
   OR CommandLine =~ 'dbgpt|docker.*3306'

Deploy this as a hunt across all Linux servers and container hosts. Any 0.0.0.0:3306 listener on a host that isn't an approved database server is a finding. Correlate container PIDs back to docker inspect output to identify the owning compose project.

Remediation / Hardening Script

Run this Bash script on hosts where DB-GPT is (or may be) deployed. It identifies exposed MySQL containers, checks for the vulnerable configuration, and applies immediate containment.

Bash / Shell
#!/usr/bin/env bash
# CVE-2026-77933 triage + containment for DB-GPT default docker-compose MySQL exposure
# Run as root (or with docker group membership) on any host suspected of running DB-GPT.

set -euo pipefail

echo "=== [1] Identifying running MySQL containers ==="
docker ps --format '{{.ID}} {{.Names}} {{.Image}} {{.Ports}}' | grep -i -E 'mysql|mariadb' || echo "No MySQL containers found."

echo ""
echo "=== [2] Checking port bindings — 0.0.0.0:3306 is the vulnerable pattern ==="
for cid in $(docker ps -q --filter "ancestor=mysql" 2>/dev/null; docker ps -q | xargs -r docker inspect -f '{{.Id}} {{.Config.Image}}' 2>/dev/null | grep -i -E 'mysql|mariadb' | awk '{print $1}'); do
  docker inspect "$cid" -f '{{.Name}} {{json .HostConfig.PortBindings}}'
done

echo ""
echo "=== [3] Checking for hardcoded MYSQL_ROOT_PASSWORD in environment ==="
for cid in $(docker ps -q); do
  img=$(docker inspect "$cid" -f '{{.Config.Image}}')
  if echo "$img" | grep -qi -E 'mysql|mariadb'; then
    echo "--- Container: $img ($cid)"
    docker inspect "$cid" -f '{{range .Config.Env}}{{println .}}{{end}}' | grep -i 'MYSQL_ROOT_PASSWORD' || echo "    (no MYSQL_ROOT_PASSWORD env found)"
  fi
done

echo ""
echo "=== [4] Locating DB-GPT compose files with vulnerable configuration ==="
grep -rIl --include='docker-compose*.y*ml' -E 'MYSQL_ROOT_PASSWORD|dbgptnet' /opt /srv /home /root 2>/dev/null | while read -r f; do
  echo "FOUND: $f"
  grep -nE 'MYSQL_ROOT_PASSWORD|3306:3306|"3306"' "$f" || true
done

echo ""
echo "=== [5] Immediate containment options (review before executing) ==="
cat <<'EOF'
CONTAINMENT — pick one:

(a) Rebind MySQL to loopback only (recommended, no downtime to app on same host):
    Edit docker-compose.yml MySQL service ports from:
      - "3306:3306"
    to:
      - "127.0.0.1:3306:3306"
    Then: docker compose up -d --force-recreate

(b) Block 3306 at the host firewall right now:
    iptables -I INPUT -p tcp --dport 3306 ! -i lo -j DROP
    (or with ufw): ufw deny 3306/tcp

(c) Rotate credentials (mandatory regardless of a/b):
    docker exec -it <mysql-container> mysql -u root -p<old-static-password> \
      -e "ALTER USER 'root'@'%' IDENTIFIED BY '<new-strong-unique-password>'; \
          DELETE FROM mysql.user WHERE User='root' AND Host='%'; \
          CREATE USER 'dbgpt'@'%' IDENTIFIED BY '<unique-password>'; \
          GRANT SELECT,INSERT,UPDATE,DELETE ON dbgpt.* TO 'dbgpt'@'%'; \
          FLUSH PRIVILEGES;"
    # Update DB-GPT's connection config to use the least-privilege 'dbgpt' account.
EOF

echo ""
echo "=== [6] Check MySQL general log for signs of prior unauthorized access ==="
for cid in $(docker ps -q); do
  img=$(docker inspect "$cid" -f '{{.Config.Image}}')
  if echo "$img" | grep -qi -E 'mysql|mariadb'; then
    echo "--- Recent auth/file-access events in $img ($cid):"
    docker logs --since 720h "$cid" 2>&1 | grep -iE 'Access denied|INTO OUTFILE|LOAD DATA|Access granted' | tail -50 || echo "    (no matching events)"
  fi
done

The script is deliberately non-destructive — it prints containment commands for review rather than auto-applying firewall changes, because blindly dropping 3306 can break the DB-GPT application itself if services communicate over the host interface rather than the internal bridge network.

Remediation

Treat this as a three-track response: fix forward, contain now, and hunt backwards.

  1. Upgrade and reconfigure (permanent fix)

    • Upgrade DB-GPT to a version later than 0.8.2 once the upstream fix is published — monitor the NVD entry and the DB-GPT GitHub repository/security advisories for the patched release.
    • Regardless of version, never deploy the stock compose file unchanged. Replace the hardcoded MYSQL_ROOT_PASSWORD with a unique, randomly generated secret injected via Docker secrets or an environment file excluded from version control (chmod 600 .env).
    • Change the port binding from 3306:3306 to 127.0.0.1:3306:3306, or remove the published port entirely if only sibling containers on dbgptnet need access (inter-container traffic does not require published ports).
    • Delete the root@% account. Create a least-privilege application user scoped to the DB-GPT schema with no FILE, SUPER, or GRANT OPTION privileges.
    • Set secure_file_priv to a dedicated, empty directory (or NULL semantics via disabling it in newer MySQL) to neutralize INTO OUTFILE / LOAD_FILE even if credentials leak again.
  2. Contain immediately (same day)

    • Firewall TCP/3306 to approved sources only — host-level iptables/nftables, cloud security groups, and network ACLs. There is no legitimate reason for MySQL in an AI tooling stack to be internet-reachable.
    • Inventory for shadow deployments: scan your environment (and your external attack surface — your own public IP ranges, via Shodan/Censys or an EASM tool) for open 3306 listeners. Developers stand up DB-GPT PoCs on cloud VMs constantly; assume at least one exists outside your CMDB.
    • Rotate any credentials, API keys, or downstream database connection strings that were stored in the DB-GPT instance's tables — assume they are compromised if the instance was ever reachable.
  3. Hunt backwards (assume breach)

    • Review MySQL logs (error log for auth events, general/audit log for queries) on any exposed instance for the IOCs in the Sigma rules above: remote root auth, INTO OUTFILE, LOAD DATA, UDF loads (CREATE FUNCTION ... SONAME).
    • On the host, check for artifacts of file-write abuse: unexpected files in the MySQL data directory, new entries in cron, modified .ssh/authorized_keys, webshells if a web server shares the host, and new SUID binaries.
    • Check container runtime logs for unexpected docker exec or new containers attached to dbgptnet.

Deadline guidance: No CISA KEV-mandated remediation date exists for this CVE as of publication, but given a CVSS 9.8 with a public, copy-pasteable exploitation path, apply containment within 24 hours for internet-exposed instances and 7 days for internal-only deployments. Do not let the absence of a KEV listing dictate your urgency — KEV tracks confirmed exploitation, and by the time a hardcoded-password bug shows up there, your data is already gone.

The Bigger Lesson

CVE-2026-77933 is not really a MySQL vulnerability — it's a secure-by-default failure in AI tooling, and it's part of a pattern we've watched accelerate through 2025 and into 2026: AI frameworks shipped for developer convenience with credentials in plaintext, debug endpoints enabled, and admin surfaces bound to 0.0.0.0. Every one of these "PoC-grade" defaults becomes production-grade exposure because PoCs never get torn down. If your organization is adopting LLM/AI data tooling, your vulnerability management program needs a dedicated workstream for it: these projects move fast, ship insecure defaults, and sit directly adjacent to your crown-jewel data. Treat every AI framework deployment as untrusted until your own review proves otherwise.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.