Attribution. This is an original English rewrite based on the article “Critical Remote Code Execution (RCE) in Roundcube, CVE-2025-49113: Your Email is Not Safe!” by AirCorridor on Hackers Arise (published 25 July 2025). The technical analysis, walkthrough and screenshots are the original author’s work; this page paraphrases the prose in our own words, preserves every screenshot at its original reading position, and links back to the source. The published PoC referenced here is by FearsOff: github.com/fearsoff-org/CVE-2025-49113.
Executive Summary
CVE-2025-49113 is a critical authenticated remote-code-execution flaw in Roundcube, the open-source webmail client shipped by default with cPanel, Plesk, and a long tail of shared-hosting control panels. The root cause is a PHP object deserialization primitive sitting inside Roundcube’s custom session-handling code: the _from parameter of the attachment-upload endpoint is normalised so loosely that an attacker can smuggle PHP-serialized object data into the user’s session, and the next session reload deserialises it into live objects whose magic methods give code execution under the web-server user.
The vulnerability affects every Roundcube build from 1.1.0 through 1.6.10 — nearly a decade of releases — and is reported to expose more than 53 million hosts across the open internet. Exploitation requires valid webmail credentials, which is a low bar in any environment that has ever leaked, brute-forced, or phished a single mailbox; once authenticated, an attacker can drop a reverse shell and pivot from the webmail host into the wider hosting backend. FearsOff has published a working proof-of-concept on GitHub. The article below walks through the root cause, the buggy code path, and the FearsOff PoC end-to-end.
Understanding the Root Cause
CVE-2025-49113 is at its core a PHP object deserialization bug that abuses two weak points at once: insufficient input validation on the upload form and a hand-rolled session serializer that does not safely tolerate attacker-controlled characters. The vulnerable code lives in program/actions/settings/upload.php, where the _from HTTP parameter — intended to identify the upload context (“edit-identity”, “add-response”, etc.) — is taken in, lightly massaged, and then fed straight into session storage.
PHP object deserialization vulnerabilities arise whenever an application reconstructs untrusted serialized data into live PHP objects without validating their class or contents. During the rebuild, PHP automatically invokes magic methods on those objects — __construct(), __destruct(), __wakeup(), and friends — and any attacker who controls the object’s properties effectively controls what those methods do. In a real-world deployment that bundles common PHP libraries, this almost always lines up with a chained gadget that ends in code execution.

_from parameter ends up being deserialised back into PHP objects through Roundcube’s session-storage path. Source: original article on Hackers Arise.What makes CVE-2025-49113 particularly delicate is the second weak point: Roundcube does not use stock PHP session serialization. It uses a custom pipe-delimited format with its own escaping rules for control characters, and that custom serializer mishandles the exclamation mark (!) in particular. The exclamation mark is treated as an in-band marker but the parser does not re-validate the structure that follows it, which is exactly the gap an attacker walks through — corrupting the session structure and slipping arbitrary serialized objects into the stream so the next reload deserialises them.

Detailed Code Flow Analysis
The bug shows up in a multi-step chain that begins the moment a logged-in user submits a file through Roundcube’s settings interface. The application pulls the _from parameter out of the HTTP request with rcube_utils::get_input_string(). In legitimate usage this carries a context string like edit-identity or add-response — identifiers that downstream code uses to decide where the uploaded attachment belongs.
The processing applied to that value is intentionally minimal: a regular expression strips any leading add- or edit- prefix, and any dot characters are converted to hyphens. The result is assigned to a local $type variable and then concatenated with the literal string .files to form a session key. Crucially, no allow-list validation is performed on the remaining content — any character that is not a dot or a prefix survives untouched into the session, including the exclamation marks and pipes that the custom serializer treats as control characters.

program/actions/settings/upload.php. The _from parameter is pulled out, lightly rewritten, then dropped into session storage as the key prefix — with no validation against the custom serializer’s control characters. Source: original article on Hackers Arise.Next the application calls $rcmail->session->append($type . '.files', $id, $attachment). Roundcube’s session layer checks how long it has been since the last reload — if more than 0.5 seconds have passed it forces a reload to keep the session view consistent. That timer is what turns a write primitive into a deserialization primitive: the attacker-poisoned write triggers an immediate read from the same store.
The reload runs Roundcube’s custom session_decode() over the serialized blob. That function walks the pipe-delimited string, hits the attacker’s injected exclamation mark, treats it as a structural marker, and then, without re-checking that the following bytes belong to a legitimate session entry, hands the trailing data to PHP’s native unserialize(). Native unserialize() sees a perfectly-formed serialized object, instantiates it, and fires whatever magic methods are appropriate — which, given any reasonable PHP-side gadget chain, results in code execution.
The exploitation path therefore boils down to: (1) log in to Roundcube with any valid mailbox credentials, (2) POST to the settings-upload endpoint with a _from value that carries a serialized payload wrapped in the right control characters, (3) wait for the next session reload, and (4) receive a shell. The FearsOff PoC packages this entire flow into a single PHP CLI tool.
Exploitation Walkthrough (FearsOff PoC)
A working proof-of-concept exploit for CVE-2025-49113 is published by FearsOff on GitHub at github.com/fearsoff-org/CVE-2025-49113. Cloning it from Kali takes the usual two commands:
kali> git clone https://github.com/fearsoff-org/CVE-2025-49113
kali> cd CVE-2025-49113
The PoC is a single PHP script that takes four positional arguments — the target Roundcube URL, valid mailbox credentials, and the shell command to execute on the remote host:
kali> php CVE-2025-49113.php target_url username password command
For the command argument the original walkthrough uses ncat -lvnp 4444 -e /bin/bash — opening a bind shell on the target’s port 4444 that re-execs /bin/bash on every incoming connection. (Operationally a reverse shell is usually a better fit, but a bind shell keeps the demo trivially short.)

Once the PoC reports success, the attacker connects to the bind shell from their own machine with a plain nc:
kali> nc <IP> 4444

nc after a successful CVE-2025-49113 exploitation. Source: original article on Hackers Arise.That shell runs as the web-server user (typically www-data, apache, or whatever account the cPanel / Plesk integration assigns to PHP-FPM). From there, classic post-exploitation applies: enumerate other tenants on the same host, harvest mailbox contents and IMAP credentials from the Roundcube config, look for a kernel or SUID bug for privilege escalation, and pivot deeper into the hosting fabric. The shared-hosting failure mode is particularly painful because every additional mailbox served by the same Roundcube instance is now reachable from the attacker’s shell.
Key Takeaways
- The bug is authenticated RCE, not pre-auth — but any leaked, weak, or phishable mailbox credential turns it into a full host compromise. Treat “authenticated” as a speed bump, not a barrier.
- Custom serializers are landmines. Roundcube’s decision to maintain its own pipe-and-bang session format is exactly why
!works as an injection oracle here. The fix removes the trust placed in attacker-controlled characters at parse time. - Insufficient input validation, not exotic chaining, is the keystone. The
_fromparameter only ever needs to be one of a small, fixed set of strings. The vulnerable code merely strips known prefixes and replaces dots; it does not allow-list the result. - The vulnerability hid for almost a decade across Roundcube 1.1.0–1.6.10. Open-source maturity is not the same as audit coverage — especially in custom session and serialisation layers.
- The footprint is enormous. Roundcube is the default webmail in cPanel and Plesk, so this single bug class touches the hosting stack used by a large share of the small-business and shared-hosting market.
- A weaponised PoC is public. Treat any unpatched Roundcube instance as already opportunistically targeted.
Hardening Checklist
- Patch to Roundcube 1.6.11 / 1.5.10 or later. The upstream fixes for CVE-2025-49113 land in those release branches; verify your cPanel / Plesk / distro package has actually picked them up rather than trusting the major-version label alone.
- Audit Roundcube exposure. Inventory every host running Roundcube — including the ones shipped by control panels and forgotten on a sub-domain — and decommission, firewall, or auth-gate any instance that does not need to be on the public internet.
- Enforce strong, unique mailbox credentials and MFA. The exploit needs valid credentials; password spraying and credential stuffing against the webmail login are the obvious precursors. Rate-limit, geo-filter, and front the login with reCAPTCHA or a WAF challenge as appropriate.
- Run Roundcube under a least-privilege PHP-FPM pool. A bind shell as
www-datashould not be able to read every other tenant’s mail spool. Per-vhost pools,open_basedir, and proper filesystem ACLs limit blast radius. - Add WAF and IDS coverage for the upload endpoint. Block POSTs to
/?_task=settings&_action=uploadwhose_fromparameter contains control characters (!,|, NUL, etc.) or unusually long serialized-PHP-shaped payloads (O:,a:,s:). Alert on the same pattern even when not blocked. - Hunt retroactively. Diff your Roundcube web logs against the disclosure date and look for POSTs to the upload endpoint with anomalous
_fromvalues, followed by outbound connections from the web-server user. The published PoC is straightforward to fingerprint. - Rotate mailbox passwords after patching on any instance that was exposed to the internet for a meaningful window between disclosure and patch — if a shell was obtained, the IMAP credentials inside the Roundcube config are trivially harvestable.
- Treat custom serializers as audit hot-spots. Any in-house code that round-trips structured data through string formats with control characters earns the same scrutiny that
unserialize()on untrusted input would.
Conclusion
CVE-2025-49113 is a textbook reminder that the boring, mature corners of widely-deployed open-source software still hide serious security flaws. A single under-validated parameter, plus a hand-rolled serialiser with one missing structural check, plus a session layer that reloads on a half-second timer, add up to authenticated remote code execution on millions of webmail hosts — many of which are the default webmail on shared-hosting boxes that nobody actively monitors. Patch the package, audit the exposure, harden the auth front-end, and watch the upload endpoint — in that order.
References
- Original write-up — AirCorridor, Hackers Arise: Critical Remote Code Execution (RCE) in Roundcube, CVE-2025-49113: Your Email is Not Safe!
- FearsOff public PoC — github.com/fearsoff-org/CVE-2025-49113
- Roundcube project — roundcube.net
Full credit for the original walkthrough, code-flow analysis, and screenshots goes to AirCorridor on Hackers Arise. Read the original at hackers-arise.com.

