← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-48842 · CWE-89 · Disclosed 2026-05-25

Roundcube Webmail 1

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a booby-trapped side door, not the front gate

CVE-2026-48842 is a pre-authentication SQL injection in Roundcube Webmail's virtuser_query plugin, fixed in 1.6.16 and 1.7.1. The bug sits in the plugin's username/email lookup path, where user-controlled login data is substituted into administrator-defined SQL templates using preg_replace(); the fix swaps that logic to str_replace(). The vulnerable population is not all Roundcube: it is Roundcube 1.6.x < 1.6.16 and 1.7.0 with virtuser_query explicitly enabled.

The vendor's HIGH 8.1 score is fair in a lab because the flaw is pre-auth, remote, and can hit a backend SQL store before login. In production, though, the real-world population is much narrower: virtuser_query is a bundled but not automatically loaded plugin, typically used only in DB-backed virtual-user mail setups. That plugin gate is the decisive friction point, so this lands lower for enterprise patch prioritization than the raw CVSS suggests.

"Pre-auth SQLi sounds urgent, but this one hides behind a non-default Roundcube plugin and niche deployment pattern."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find exposed Roundcube that actually uses the plugin

An operator starts with internet enumeration using Censys or Shodan to locate exposed Roundcube login pages, then has to determine whether the target uses the virtuser_query login-mapping plugin. Exposure of Roundcube itself is common; exposure of this specific plugin path is not externally obvious and usually requires either error behavior, config leakage, or prior environmental knowledge.
Conditions required:
  • Roundcube is reachable from the internet or attacker-accessible network
  • Instance runs 1.6.x < 1.6.16 or 1.7.0
  • virtuser_query is enabled in config/config.inc.php
Where this breaks in practice:
  • virtuser_query is a bundled plugin but not loaded until enabled
  • Version fingerprinting does not prove the vulnerable plugin is active
  • Many enterprises do not use DB-backed virtual-user mapping in Roundcube at all
Detection/coverage: ASM tools and search engines can find exposed Roundcube, but they generally cannot confirm plugin activation. Version-only scanners will overcount.
STEP 02

Reach the pre-auth lookup path

Using Burp Suite or a custom HTTP client, the attacker submits crafted login identifiers that force the plugin to run its user/email lookup query before authentication completes. The vulnerable code path is tied to how the plugin converts a supplied username or email into SQL using configured %u or %m placeholders.
Conditions required:
  • Login flow invokes virtuser_query lookups for the submitted identifier
  • Webmail accepts direct access to the login endpoint
Where this breaks in practice:
  • Some deployments use SSO, reverse proxies, or VPN gating that limit anonymous reachability
  • Not every login workflow exercises the vulnerable lookup functions the same way
Detection/coverage: Web logs can show repeated malformed login identifiers, but most scanners will only see 'Roundcube exposed' and not path-specific exploit attempts.
STEP 03

Bypass the escaping assumption

The exploit relies on a custom injector or sqlmap-style tamper logic to abuse the preg_replace() replacement behavior with backslashes, defeating the developer's assumption that database escaping alone was sufficient. This is why the CVSS vector carries AC:H: exploitation is not just 'append quote, win' and depends on the exact query template and database behavior.
Conditions required:
  • Attacker can craft identifiers that survive web, PHP, and DB parsing layers
  • Administrator-defined SQL template is injectable in practice
Where this breaks in practice:
  • Exploitability depends on the site-specific SQL template configured by the admin
  • Backslash handling and query semantics vary across DB engines and templates
  • No reputable public PoC was located in primary sources during this assessment
Detection/coverage: WAFs may catch noisy quote-heavy payloads, but backslash-driven bypass attempts are easy to miss if signatures are generic.
STEP 04

Turn SQL control into useful impact

If successful, the attacker can use manual SQLi extraction or sqlmap to pull data from the backing mail-user database, manipulate mappings, or potentially influence authentication-related lookups. The impact can be serious on affected systems, but it is largely bounded to the Roundcube/mail backend data path rather than a guaranteed one-shot server takeover.
Conditions required:
  • Injection is viable against the configured query
  • Database account used by Roundcube has meaningful read or write privileges
Where this breaks in practice:
  • Least-privilege DB accounts can significantly limit blast radius
  • Some deployments separate Roundcube metadata from mailbox identity stores
  • Turning SQLi into full host compromise is not inherent to this CVE
Detection/coverage: Database slow-query logs, auth anomalies, and unusual pre-auth request spikes can help, but commodity web scanners often stop at banner/version detection.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo evidence of active exploitation found in the Roundcube advisory, NVD references, or CISA KEV at assessment time.
KEV statusNot listed in CISA KEV; the CISA Roundcube search page shows older Roundcube entries but not CVE-2026-48842.
PoC availabilityNo reputable public PoC or Exploit-DB entry was located in primary sources. The exploit path is understandable from the patch diff, but public weaponization was not confirmed.
EPSS0.00076 from FIRST-sourced telemetry in the user intel; that is very low expected near-term exploitation probability.
CVSS interpretationCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H correctly reflects *remote pre-auth* reachability, but the high attack complexity matters here because exploitability depends on plugin state and query-template specifics.
Affected versionsRoundcube Webmail 1.6.x before 1.6.16 and 1.7.0 before 1.7.1, only when virtuser_query is enabled.
Fixed versionsUpstream fixed in 1.6.16 and 1.7.1. Debian also backported fixes to bullseye 1.4.15+dfsg.1-1+deb11u9, bookworm 1.6.5+dfsg-1+deb12u9, and trixie 1.6.16+dfsg-0+deb13u1.
Exposure realityRoundcube as a product is broadly exposed on the internet; Censys reported 2,473,116 exposed Roundcube instances in a 2025 advisory. That amplifies attention, but it does not mean those hosts use virtuser_query.
Disclosure timelineUpstream advisory published 2026-05-24; CVE/NVD record published 2026-05-25.
ReporterRoundcube credits the issue to researcher skull in the upstream security advisory.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (6.2/10)

The decisive factor is plugin gating: this is not a bug in default Roundcube login flow, it is a bug in a bundled plugin that admins must explicitly enable for DB-backed virtual-user lookups. That sharply reduces the reachable population, so despite the ugly pre-auth SQLi label, this is not a fleet-wide fire drill unless you know you run virtuser_query.

HIGH Affected version and fix boundaries
HIGH `virtuser_query` requires explicit enablement
MEDIUM Real-world prevalence of `virtuser_query` in enterprise deployments

Why this verdict

  • Down from vendor HIGH for plugin gating: virtuser_query is bundled, but Roundcube's own plugin docs state a plugin is not used until added to the plugins config array. That turns 'all exposed Roundcube' into a much smaller subset.
  • Down again for compounded prerequisites: attacker needs anonymous network reachability, a vulnerable Roundcube build, the specific plugin enabled, and a site-specific SQL template that is exploitable through the backslash/preg-replace behavior. Each prerequisite narrows population and raises operational friction.
  • Held at MEDIUM because the entry point is still pre-auth remote: if you do use this plugin on an internet-facing host, the attacker hits SQL before login and can potentially extract or manipulate mail-user data without credentials.

Why not higher?

This is not higher because the vulnerable code is behind a non-default plugin and a specific deployment model. There is also no KEV listing, no confirmed active exploitation, and no reputable public PoC located during the assessment, so there is no external signal that attackers are mass-operationalizing it right now.

Why not lower?

This is not lower because the bug is still pre-authentication and network-reachable on affected systems. For organizations that do run virtuser_query on exposed webmail, the blast radius can include sensitive backend mail-user data and authentication-adjacent mappings, which is too much impact to relegate to backlog-only hygiene.

05 · Compensating Control

What to do — in priority order.

  1. Disable virtuser_query where unused — If business logic does not require DB-backed virtual-user lookups, remove virtuser_query from the Roundcube plugins array. For a MEDIUM verdict there is no noisgate mitigation SLA; do this in the next normal change window and then patch within the remediation window.
  2. Restrict anonymous reachability to webmail — Put Roundcube behind VPN, SSO access control, IP allowlists, or reverse-proxy authentication where practical. This does not fix the bug, but it removes the unauthenticated internet path and is worth doing during routine hardening since there is no mitigation SLA for MEDIUM.
  3. Review DB account privileges — Check the database account used by Roundcube and the mail-user lookup path; keep it read-only where possible and scoped to only required tables. That reduces impact if SQLi is achieved, and it should be folded into normal hardening before the 365-day remediation deadline.
  4. Increase telemetry on login anomalies — Log and alert on unusual pre-auth login identifiers, repeated failures with escaping characters, and DB slow-query spikes against lookup tables. This is detective control only, but it gives you a chance to spot exploit development while you work through normal patch cycles.
What doesn't work
  • A generic version-only scan does not tell you whether virtuser_query is enabled, so it will inflate exposure counts and create false urgency.
  • EDR on the Linux host does not meaningfully stop a pre-auth SQL parser bug by itself; the relevant choke points are web access controls, plugin state, and DB privilege scope.
  • Relying on a WAF alone is weak here because the issue involves backslash handling and application-specific substitution behavior, not just obvious ' OR 1=1 -- payloads.
06 · Verification

Crowdsourced verification payload.

Run this on the Roundcube host as a user who can read the Roundcube install directory and config/config.inc.php—root is helpful but not strictly required. Invoke it with the install root, for example: bash verify_cve_2026_48842.sh /var/www/roundcube; it checks version evidence plus whether virtuser_query is enabled and prints VULNERABLE, PATCHED, or UNKNOWN.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# verify_cve_2026_48842.sh
# Check Roundcube CVE-2026-48842 exposure.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -u

TARGET="${1:-}"

find_root() {
  local candidates=()
  if [[ -n "$TARGET" ]]; then
    candidates+=("$TARGET")
  fi
  candidates+=(
    "/var/www/roundcube"
    "/var/lib/roundcube"
    "/usr/share/roundcube"
    "/usr/share/roundcubemail"
    "/opt/roundcube"
    "/srv/roundcube"
  )

  for d in "${candidates[@]}"; do
    [[ -d "$d" ]] || continue
    if [[ -f "$d/index.php" && -d "$d/plugins" ]]; then
      echo "$d"
      return 0
    fi
  done
  return 1
}

version_ge() {
  # returns 0 if $1 >= $2
  if command -v dpkg >/dev/null 2>&1; then
    dpkg --compare-versions "$1" ge "$2"
    return $?
  fi
  [[ "$(printf '%s\n%s\n' "$2" "$1" | sort -V | head -n1)" == "$2" ]]
}

version_lt() {
  # returns 0 if $1 < $2
  if command -v dpkg >/dev/null 2>&1; then
    dpkg --compare-versions "$1" lt "$2"
    return $?
  fi
  [[ "$1" != "$2" ]] && [[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" == "$1" ]]
}

extract_version() {
  local root="$1"
  local v=""

  # Debian/RPM package versions first
  if command -v dpkg-query >/dev/null 2>&1; then
    v="$(dpkg-query -W -f='${Version}' roundcube 2>/dev/null || true)"
    if [[ -n "$v" ]]; then
      echo "$v"
      return 0
    fi
    v="$(dpkg-query -W -f='${Version}' roundcube-core 2>/dev/null || true)"
    if [[ -n "$v" ]]; then
      echo "$v"
      return 0
    fi
  fi

  if command -v rpm >/dev/null 2>&1; then
    v="$(rpm -q --qf '%{VERSION}-%{RELEASE}' roundcubemail 2>/dev/null || true)"
    if [[ -n "$v" && "$v" != *"not installed"* ]]; then
      echo "$v"
      return 0
    fi
  fi

  # Source installs: try common metadata files
  if [[ -f "$root/composer.json" ]]; then
    v="$(grep -Eo '"version"[[:space:]]*:[[:space:]]*"[^"]+"' "$root/composer.json" 2>/dev/null | head -n1 | sed -E 's/.*"([0-9][^"]*)"/\1/')"
    if [[ -n "$v" ]]; then
      echo "$v"
      return 0
    fi
  fi

  if [[ -f "$root/program/include/iniset.php" ]]; then
    v="$(grep -Eo '[0-9]+\.[0-9]+\.[0-9]+' "$root/program/include/iniset.php" 2>/dev/null | head -n1)"
    if [[ -n "$v" ]]; then
      echo "$v"
      return 0
    fi
  fi

  if [[ -f "$root/CHANGELOG.md" ]]; then
    v="$(grep -Eo 'Release[[:space:]]+[0-9]+\.[0-9]+\.[0-9]+' "$root/CHANGELOG.md" 2>/dev/null | head -n1 | awk '{print $2}')"
    if [[ -n "$v" ]]; then
      echo "$v"
      return 0
    fi
  fi

  return 1
}

plugin_enabled() {
  local root="$1"
  local cfg="$root/config/config.inc.php"
  [[ -f "$cfg" ]] || return 2

  # Best-effort parse: strip comments, then look for virtuser_query token.
  local content
  content="$(sed -E 's://.*$::; s:#.*$::' "$cfg" 2>/dev/null | tr '\n' ' ')"
  if echo "$content" | grep -Eq "plugins[^;]*virtuser_query"; then
    return 0
  fi
  return 1
}

ROOT="$(find_root || true)"
if [[ -z "$ROOT" ]]; then
  echo "UNKNOWN - Roundcube root not found"
  exit 2
fi

VER="$(extract_version "$ROOT" || true)"
if [[ -z "$VER" ]]; then
  echo "UNKNOWN - Could not determine Roundcube version under $ROOT"
  exit 2
fi

plugin_enabled "$ROOT"
PLUGIN_RC=$?
if [[ $PLUGIN_RC -eq 2 ]]; then
  echo "UNKNOWN - Config file missing at $ROOT/config/config.inc.php"
  exit 2
fi
if [[ $PLUGIN_RC -ne 0 ]]; then
  echo "PATCHED - virtuser_query not enabled in $ROOT/config/config.inc.php (CVE-2026-48842 path not active)"
  exit 0
fi

# Normalize upstream version prefix if package release suffixes exist.
UPSTREAM="$(echo "$VER" | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)"
if [[ -z "$UPSTREAM" ]]; then
  echo "UNKNOWN - Parsed package version '$VER' but no upstream semantic version found"
  exit 2
fi

# Vulnerable logic:
# 1.6.x before 1.6.16
# 1.7.x before 1.7.1 (practically 1.7.0)
if [[ "$UPSTREAM" =~ ^1\.6\.[0-9]+$ ]]; then
  if version_lt "$UPSTREAM" "1.6.16"; then
    echo "VULNERABLE - Roundcube $VER with virtuser_query enabled"
    exit 1
  else
    echo "PATCHED - Roundcube $VER with virtuser_query enabled, but >= 1.6.16"
    exit 0
  fi
elif [[ "$UPSTREAM" =~ ^1\.7\.[0-9]+$ ]]; then
  if version_lt "$UPSTREAM" "1.7.1"; then
    echo "VULNERABLE - Roundcube $VER with virtuser_query enabled"
    exit 1
  else
    echo "PATCHED - Roundcube $VER with virtuser_query enabled, but >= 1.7.1"
    exit 0
  fi
else
  echo "PATCHED - Roundcube $VER is outside the stated affected upstream branches, though plugin state was checked"
  exit 0
fi
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, do not mass-escalate every Roundcube server off the CVSS alone; first identify which installations actually have virtuser_query enabled, because that is the real exposure divider. For this MEDIUM verdict there is no noisgate mitigation SLA — go straight to the 365-day remediation window for the vendor fix, but in practice you should patch plugin-enabled, internet-facing Roundcube during the next routine webmail maintenance cycle and clean up plugin inventory now; per the noisgate remediation SLA, complete the actual upgrade/backport within <= 365 days.

Sources

  1. Roundcube security advisory
  2. NVD CVE record
  3. Upstream fix commit
  4. Roundcube plugin documentation
  5. Debian CVE tracker
  6. Debian security update DSA-6301-1
  7. CISA KEV catalog search for Roundcube
  8. Censys advisory showing broad Roundcube exposure
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.