CVE-2026-48842
Description
Roundcube Webmail 1.6.x before 1.6.16 and 1.7.x before 1.7.1 has Pre-authentication SQL injection in the virtuser_query plugin via a preg_replace() backslash escape bypass.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Pre-authentication SQL injection in Roundcube Webmail's virtuser_query plugin via preg_replace() backslash escape bypass in versions 1.6.x before 1.6.16 and 1.7.x before 1.7.1.
Vulnerability
A pre-authentication SQL injection vulnerability exists in the virtuser_query plugin of Roundcube Webmail 1.6.x before 1.6.16 and 1.7.x before 1.7.1. The plugin uses preg_replace() with a user-supplied pattern that allows a backslash escape bypass, enabling an unauthenticated attacker to inject arbitrary SQL queries. The vulnerable code paths are in the user2email(), email2user(), user2host(), and alias2user() functions, where preg_replace() is replaced with str_replace() in the fix commit [4]. The plugin is configurable and may not be enabled by default, but if active, it is reachable without authentication.
Exploitation
An unauthenticated attacker can send crafted requests to the Roundcube Webmail instance where the virtuser_query plugin is enabled. By providing a malicious username or email parameter that includes backslashes and SQL payloads, the attacker bypasses the preg_replace() placeholder substitution to inject SQL commands. The fix changed preg_replace() to str_replace() to prevent the regex-based escape bypass [4]. No authentication or special network position is required beyond network access to the Roundcube installation.
Impact
Successful exploitation allows the attacker to execute arbitrary SQL queries against the Roundcube database. This can lead to information disclosure (e.g., reading user credentials or email data), modification of data, or further privilege escalation. Since the injection occurs before authentication, the attacker does not need valid credentials to compromise the system.
Mitigation
Roundcube Webmail versions 1.6.16 and 1.7.1 have been patched and released on May 24, 2026 [1][2][3]. Users should immediately upgrade to the latest available version. The fix replaces preg_replace() with str_replace() in the virtuser_query plugin [4]. There is no known workaround if the plugin is enabled; disabling the plugin may mitigate the risk but is not recommended as a substitute for patching. The vulnerability is not listed in CISA's Known Exploited Vulnerabilities catalog as of the publication date.
AI Insight generated on May 25, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
2- Range: <1.6.16, <1.7.1
Patches
287124cc7136aFix pre-auth SQL injection in virtuser_query plugin via preg_replace backslash escape bypass
2 files changed · +6 −5
CHANGELOG.md+1 −0 modified@@ -5,6 +5,7 @@ - Fix potential too long value in IMAP ID command (#10136) - Security: Fix stored XSS/HTML/CSS injection in subject field of the draft restore dialog - Security: Fix CSS injection bypass in HTML sanitizer via SVG `<animate attributeName="style">` +- Security: Fix pre-auth SQL injection in `virtuser_query` plugin via preg_replace backslash escape bypass ## Release 1.6.15
plugins/virtuser_query/virtuser_query.php+5 −5 modified@@ -63,8 +63,8 @@ function user2email($p) { $dbh = $this->get_dbh(); - $sql_result = $dbh->query(preg_replace('/%u/', $dbh->escape($p['user']), $this->config['email'])); - $result = []; + $sql_result = $dbh->query(str_replace('%u', $dbh->escape($p['user']), $this->config['email'])); + $result = []; while ($sql_arr = $dbh->fetch_array($sql_result)) { if (strpos($sql_arr[0], '@')) { @@ -101,7 +101,7 @@ function email2user($p) { $dbh = $this->get_dbh(); - $sql_result = $dbh->query(preg_replace('/%m/', $dbh->escape($p['email']), $this->config['user'])); + $sql_result = $dbh->query(str_replace('%m', $dbh->escape($p['email']), $this->config['user'])); if ($sql_arr = $dbh->fetch_array($sql_result)) { $p['user'] = $sql_arr[0]; @@ -117,7 +117,7 @@ function user2host($p) { $dbh = $this->get_dbh(); - $sql_result = $dbh->query(preg_replace('/%u/', $dbh->escape($p['user']), $this->config['host'])); + $sql_result = $dbh->query(str_replace('%u', $dbh->escape($p['user']), $this->config['host'])); if ($sql_arr = $dbh->fetch_array($sql_result)) { $p['host'] = $sql_arr[0]; @@ -133,7 +133,7 @@ function alias2user($p) { $dbh = $this->get_dbh(); - $sql_result = $dbh->query(preg_replace('/%u/', $dbh->escape($p['user']), $this->config['alias'])); + $sql_result = $dbh->query(str_replace('%u', $dbh->escape($p['user']), $this->config['alias'])); if ($sql_arr = $dbh->fetch_array($sql_result)) { $p['user'] = $sql_arr[0];
3406183a9976Fix pre-auth SQL injection in virtuser_query plugin via preg_replace backslash escape bypass
2 files changed · +5 −4
CHANGELOG.md+1 −0 modified@@ -16,6 +16,7 @@ This file includes only changes we consider noteworthy for users, admins and plu - Fix MySQL upgrade on MySQL < 8.0 and MariaDB < 10.5.3 (#10188) - Security: Fix stored XSS/HTML/CSS injection in subject field of the draft restore dialog - Security: Fix CSS injection bypass in HTML sanitizer via SVG `<animate attributeName="style">` +- Security: Fix pre-auth SQL injection in `virtuser_query` plugin via preg_replace backslash escape bypass ## Release 1.7.0
plugins/virtuser_query/virtuser_query.php+4 −4 modified@@ -64,7 +64,7 @@ public function user2email($p) { $dbh = $this->get_dbh(); - $sql_result = $dbh->query(preg_replace('/%u/', $dbh->escape($p['user']), $this->config['email'])); + $sql_result = $dbh->query(str_replace('%u', $dbh->escape($p['user']), $this->config['email'])); $result = []; while ($sql_arr = $dbh->fetch_array($sql_result)) { @@ -101,7 +101,7 @@ public function email2user($p) { $dbh = $this->get_dbh(); - $sql_result = $dbh->query(preg_replace('/%m/', $dbh->escape($p['email']), $this->config['user'])); + $sql_result = $dbh->query(str_replace('%m', $dbh->escape($p['email']), $this->config['user'])); if ($sql_arr = $dbh->fetch_array($sql_result)) { $p['user'] = $sql_arr[0]; @@ -117,7 +117,7 @@ public function user2host($p) { $dbh = $this->get_dbh(); - $sql_result = $dbh->query(preg_replace('/%u/', $dbh->escape($p['user']), $this->config['host'])); + $sql_result = $dbh->query(str_replace('%u', $dbh->escape($p['user']), $this->config['host'])); if ($sql_arr = $dbh->fetch_array($sql_result)) { $p['host'] = $sql_arr[0]; @@ -133,7 +133,7 @@ public function alias2user($p) { $dbh = $this->get_dbh(); - $sql_result = $dbh->query(preg_replace('/%u/', $dbh->escape($p['user']), $this->config['alias'])); + $sql_result = $dbh->query(str_replace('%u', $dbh->escape($p['user']), $this->config['alias'])); if ($sql_arr = $dbh->fetch_array($sql_result)) { $p['user'] = $sql_arr[0];
Vulnerability mechanics
Root cause
"Use of `preg_replace()` instead of `str_replace()` allows backslash escape sequences in attacker-controlled input to bypass SQL escaping and inject arbitrary SQL."
Attack vector
An unauthenticated attacker can inject SQL by providing a username or email containing a backslash followed by a character that `preg_replace()` interprets as a backreference (e.g., `\0` or `\1`). Because `preg_replace()` processes the replacement string for backreference escapes, a backslash in the attacker-supplied value can break out of the `$dbh->escape()` sanitization and inject arbitrary SQL into the query. The attack is pre-authentication because the `virtuser_query` plugin is invoked during the login/identity-resolution phase before a session is established [patch_id=2473674][patch_id=2473673].
Affected code
The vulnerability resides in `plugins/virtuser_query/virtuser_query.php` across four functions: `user2email`, `email2user`, `user2host`, and `alias2user`. Each function used `preg_replace()` with a pattern like `'/%u/'` or `'/%m/'` to substitute user-controlled input into SQL queries constructed from plugin configuration values (`$this->config['email']`, `$this->config['user']`, `$this->config['host']`, `$this->config['alias']`).
What the fix does
The fix replaces `preg_replace()` with `str_replace()` in all four functions (`user2email`, `email2user`, `user2host`, `alias2user`) [patch_id=2473674][patch_id=2473673]. Unlike `preg_replace()`, `str_replace()` performs a literal string substitution and does not interpret backslash sequences or backreferences. This closes the bypass because an attacker's backslash characters are treated as plain text and remain properly escaped by `$dbh->escape()` before reaching the SQL query.
Preconditions
- configThe virtuser_query plugin must be enabled in the Roundcube configuration.
- inputThe attacker must be able to supply a username or email value (e.g., during login or email address resolution) that reaches one of the four vulnerable functions.
- authNo authentication is required; the plugin is invoked pre-authentication.
Generated on May 25, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/roundcube/roundcubemail/commit/3406183a9976e36f992d3468f37d0e2346526ee9mitre
- github.com/roundcube/roundcubemail/commit/87124cc7136a48b5fa9d2b40dfead6e9dcaeaf4bmitre
- github.com/roundcube/roundcubemail/releases/tag/1.6.16mitre
- github.com/roundcube/roundcubemail/releases/tag/1.7.1mitre
- roundcube.net/news/2026/05/24/security-updates-1.6.16-and-1.7.1mitre
News mentions
0No linked articles in our index yet.