A ten-year-old deserialization bug in the webmail app your hosting provider ships by default
CVE-2025-49113 is a PHP object deserialization flaw in Roundcube's file upload handler (program/actions/settings/upload.php). The _from request parameter is passed to unserialize() after being fetched from session state without validation, letting an authenticated user instantiate arbitrary PHP objects and trigger destructor/magic-method gadget chains that end in command execution as the web server user. The bug has lived in the codebase for over ten years and affects Roundcube 1.1.0 through 1.5.9 and 1.6.0 through 1.6.10. Fixed in 1.5.10 and 1.6.11 (June 1, 2025).
Vendor's 9.9 CRITICAL rating is accurate and if anything conservative. Yes, PR:L (low-privilege auth required) normally warrants a downgrade — but Roundcube is the *default* webmail on cPanel, Plesk, ISPConfig, and countless shared-hosting stacks, meaning tens of thousands of instances are internet-facing with self-service user accounts, and valid credentials are a commodity on infostealer markets. CISA added it to KEV on June 30, 2025, weaponized exploits were being sold within 48 hours of the FEARSOFF advisory, and mass scanning began the same week. This is the rare case where the friction (auth requirement) is neutralized by the deployment model.
4 steps from start to impact.
Obtain valid Roundcube credentials
- Reachable Roundcube login (usually /mail, /webmail, /roundcube)
- Any single valid mailbox credential
- Enterprise deployments behind SSO/MFA block credential reuse
- IP allowlisting on the webmail vhost breaks external access
errors log and IMAP auth logs; Shodan/Censys indexes >100k exposed instancesCraft malicious serialized payload
GuzzleHttp\Psr7\FnStream or Roundcube's own session objects — into a system()/passthru() call. The payload is delivered via the _from parameter in a POST to ?_task=settings&_action=upload-display.- Working PoC (widely public since June 3, 2025)
- Session cookie from step 1
- Custom PHP disable_functions lists can defang some gadgets
- PHP-FPM chroot / open_basedir limits post-exec pivoting
CVE-2025-49113, and Metasploit exploit/multi/http/roundcube_unserialize_rce all detect and weaponizeTrigger unserialize() → RCE as web user
www-data/apache/nobody (or on cPanel, as the mailbox owner via suEXEC — which is *worse* because it's a real UID with a home directory).- PHP process reaches the vulnerable code path (default config)
- No WAF rule blocking serialized PHP object markers in POST bodies
- ModSecurity CRS 4.x rule 944150 catches the
O:object marker in some payloads - SELinux/AppArmor confinement on Debian/Ubuntu limits egress
_action=upload-display with abnormal body sizes; EDR flags php spawning sh/bashLoot mailboxes and pivot
- RCE from step 3
- Isolated per-tenant PHP-FPM pools contain blast radius to one mailbox
- IMAP creds encrypted with strong per-install DES key (still recoverable from config)
imap LOGIN volume from webmail host; outbound to attacker C2The supporting signals.
| In-the-wild status | Active mass exploitation since ~June 4, 2025. CISA KEV added 2025-06-30. Observed by GreyNoise, watchTowr, and CERT-FR. |
|---|---|
| Public PoCs | FEARSOFF advisory (Kirill Firsov), hakaioffensive/CVE-2025-49113, watchTowr Labs deep-dive, Metasploit module roundcube_unserialize_rce, Nuclei template. |
| EPSS | 0.89462 (~top 1-2% percentile) — reflects observed exploitation, not just prediction. |
| KEV status | Listed 2025-06-30. Federal remediation deadline was 2025-07-21. |
| CVSS 3.1 vector | AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H — network-reachable, low complexity, low-priv auth, scope change (webmail user → host), full CIA impact. 9.9 CRITICAL — accurate. |
| Affected versions | Roundcube 1.1.0 through 1.5.9 and 1.6.0 through 1.6.10 (bug present ~10 years). |
| Fixed versions | 1.5.10 and 1.6.11 (released 2025-06-01). Debian: 1.6.5+dfsg-1+deb12u4. RHEL/EPEL: 1.6.11-1.el9. cPanel pushed automatic update in early June. |
| Exposure data | Censys/Shodan indexed ~120,000–130,000 internet-facing Roundcube instances in June 2025; ProjectDiscovery's telemetry showed >30% still unpatched two weeks post-disclosure. |
| Disclosure | Coordinated. Reported by Kirill Firsov (FEARSOFF). Patch and advisory published 2025-06-01, CVE assigned 2025-06-02. |
| CWE | CWE-502 (Deserialization of Untrusted Data). |
noisgate verdict.
Verdict stays CRITICAL because Roundcube is a canonical high-value-role component — it *is* the mail plane for hosting providers and mid-market IT, so successful exploitation ends in mailbox mass-harvest and password-reset pivoting across the entire customer base. The single decisive factor is active KEV-listed exploitation against a target class whose ~120k internet-facing installs regularly accept self-service or infostealer-obtained credentials, neutralizing the PR:L friction.
Why this verdict
- KEV + EPSS 0.89 — this is not theoretical. CISA listed it within 4 weeks of disclosure and EPSS is in the top-1% band because exploitation is *measured*, not predicted.
- Role multiplier — webmail plane: Roundcube's canonical role is the customer-facing mail UI for hosting providers (cPanel, Plesk, ISPConfig ship it by default). Chain succeeds in that role → outcome is per-tenant RCE + IMAP credential harvest + session theft across every mailbox on the vhost. This is the fleet-scale outcome and it dominates the verdict.
- PR:L friction is nullified by the deployment model — hosting providers *sell* accounts, and infostealer markets sell mailbox creds for pennies. On multi-tenant hosts the auth requirement is a $2 speed bump, not a defense.
- Ten-year bug window means 100% of unpatched instances on any version between 1.1.0 and 1.6.10 are vulnerable — no narrow band to hide in.
- Public weaponized exploits in Metasploit, Nuclei, and standalone Python — no skill barrier.
Why not higher?
There is no higher bucket than CRITICAL, but note the score sits at 9.4 rather than 10.0 because PR:L is still a real friction on properly-segmented enterprise deployments (SSO-fronted webmail with no self-service signup), and because a single Roundcube RCE does not automatically pivot to domain-level compromise the way an AD or hypervisor bug would.
Why not lower?
Downgrading to HIGH would require ignoring the KEV listing and the observed mass exploitation of ~120k exposed instances. The PR:L auth requirement, which normally justifies a downgrade, is defeated in practice by infostealer credential markets and self-service signup on hosting stacks — so it cannot be treated as meaningful friction here.
What to do — in priority order.
- Restrict
/mail,/webmail,/roundcubeto VPN or IP allowlist at the reverse proxy — Kills the credential-brute-force and self-service-signup path. Deploy within 3 days per noisgate mitigation SLA — Nginxallow/denyor Cloudflare Access rule takes <1 hour. - Deploy WAF rule blocking PHP serialized object markers in POST bodies to Roundcube endpoints — ModSecurity/CRS rule matching regex
(?:^|[&;])_from=[^&]*O%3A\d+%3Ablocks the exploit payload. Turn on within 3 days; low false-positive risk since users don't submit serialized objects. - Force session revocation and password reset for all Roundcube users — If you've been exposed for >30 days, assume some sessions/creds are compromised. Truncate the
sessiontable, rotate thedes_keyinconfig.inc.php, force IMAP password reset. Do this at the same time as the patch. - Upgrade to 1.5.10 or 1.6.11 (or distro backport) — The only durable fix. Debian
apt install roundcube, EPELdnf update roundcubemail, or upstream tarball. Within 90 days per noisgate remediation SLA — realistically do it in the first maintenance window. - Enable MFA in front of Roundcube via reverse-proxy SSO — Roundcube's built-in
twofactor_gauthenticatorplugin does not gate the vulnerable code path — put MFA at the *proxy* layer (Authelia, oauth2-proxy, Cloudflare Access). Kills 90% of stolen-credential replays.
- Roundcube's built-in 2FA plugin — the vulnerable
upload-displayaction runs after session establishment; TOTP prompts don't cover the exploit surface once creds are known. - Fail2ban on login failures — attackers with infostealer-sourced creds succeed on the first try, no failures to detect.
- PHP
disable_functions=exec,system,passthru,shell_exec— helpful but not sufficient; gadget chains can still write webshells to disk or usemail()for command injection on some configs. - Blocking
unserialize()at WAF level generically — Roundcube legitimately uses PHP sessions; you must scope the block to the_fromparameter on the upload endpoint.
Crowdsourced verification payload.
Run on each Roundcube host as any user with read on the install directory. Invoke as ./check_cve_2025_49113.sh /var/www/roundcube (default path /var/www/html/roundcube if none given). No root required unless the install dir is mode 0700. Exits 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN.
#!/usr/bin/env bash
# noisgate check: CVE-2025-49113 Roundcube deserialization RCE
# Usage: ./check_cve_2025_49113.sh [/path/to/roundcube]
set -u
ROOT="${1:-/var/www/html/roundcube}"
VERFILE="$ROOT/program/include/iniset.php"
ALT="$ROOT/index.php"
if [[ ! -d "$ROOT" ]]; then
echo "UNKNOWN: $ROOT not found"
exit 2
fi
# Extract RCMAIL_VERSION
VER=$(grep -hRE "define\(['\"]RCMAIL_VERSION['\"]" "$ROOT/program/include/" "$ROOT/" 2>/dev/null \
| grep -oE "[0-9]+\.[0-9]+\.[0-9]+" | head -n1)
if [[ -z "$VER" ]]; then
echo "UNKNOWN: could not parse RCMAIL_VERSION in $ROOT"
exit 2
fi
echo "Detected Roundcube version: $VER"
# Compare semver. Vulnerable: 1.1.0 <= v < 1.5.10, or 1.6.0 <= v < 1.6.11
IFS='.' read -r MAJ MIN PAT <<< "$VER"
MAJ=${MAJ:-0}; MIN=${MIN:-0}; PAT=${PAT:-0}
vulnerable=0
if (( MAJ == 1 )); then
if (( MIN >= 1 && MIN <= 5 )); then
# 1.1.x - 1.5.x: fixed at 1.5.10
if (( MIN < 5 )) || (( MIN == 5 && PAT < 10 )); then
vulnerable=1
fi
elif (( MIN == 6 )); then
# 1.6.x: fixed at 1.6.11
if (( PAT < 11 )); then
vulnerable=1
fi
fi
fi
# Secondary check: look for the pre-patch unserialize call
UPLOAD="$ROOT/program/actions/settings/upload.php"
if [[ -f "$UPLOAD" ]]; then
if grep -qE "unserialize\(.*_from" "$UPLOAD" 2>/dev/null; then
echo "Confirmed: unpatched unserialize(_from) sink present."
vulnerable=1
fi
fi
if (( vulnerable == 1 )); then
echo "VULNERABLE: Roundcube $VER is affected by CVE-2025-49113. Upgrade to 1.5.10 or 1.6.11."
exit 1
fi
echo "PATCHED: Roundcube $VER is not affected."
exit 0
If you remember one thing.
_from serialized-object pattern buys you a weekend. (3) Patch to 1.5.10 or 1.6.11 (or distro backport) within the noisgate remediation SLA of ≤ 90 days for CRITICAL — practically, do it in this week's maintenance window. (4) Assume compromise on any instance that has been internet-facing and unpatched since June 1, 2025: rotate the Roundcube des_key, force IMAP password resets, hunt web-access logs for POSTs to _action=upload-display with abnormally large bodies, and check for new files under program/ or unexpected cron entries owned by the web user.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.