~60 Days as Root: A Practitioner's Take on the cPanel Pre-Auth Bypass

~60 Days as Root: A Practitioner's Take on the cPanel Pre-Auth Bypass

If you have spent any time around shared hosting, you have spent time around cPanel. I have been running into cPanel and WHM servers for longer than I care to admit, in just about every shape they come in: a single reseller box where someone wanted me to clean up after a phishing kit landed in /home/user/public_html, the multi-server WHM clusters at small regional providers, the boutique hosts who lived and died by /scripts/upcp, and more than a few enterprise environments that quietly inherited a cPanel deployment from an acquisition that nobody wanted to touch.

So when CVE-2026-41940 dropped on April 28, my first reaction was not surprise that a cPanel vulnerability existed. cPanel ships a lot of code, and any control panel sitting on the public internet on ports 2083 and 2087 has a lot of attack surface. My reaction was to read the timeline twice and then once more.

For 64 days before the public advisory, attackers had root on cPanel servers. Not user-level access. Not a single hosted site. Root. And nobody had to know a single password to get in. A crafted HTTP request was enough, and two-factor authentication made no difference. The company was told about it two weeks before the patch dropped. Their first response, per the reporting, was that nothing was wrong.

That is not a bug. That is a story about how vendor culture meets a multi-tenant trust model.

Why this CVE is different

I've patched a lot of cPanel boxes for a lot of CVEs. Most of them, you read the advisory, you note the affected versions, you push /scripts/upcp --force, you move on. Some of them are scary in theory and limited in practice. CVE-2026-41940 is the other category.

It is pre-authentication. There is no credential to brute force, no 2FA seed to steal, no phishing payload to plant. You hit the endpoint and you are root.

It hits WHM. Not the per-tenant cPanel interface. WHM is the host operator's panel, the one with full root authority over the entire server, every tenant on it, every database, every email account, every TLS certificate, every API token sitting on disk. If you compromise a single shared-hosting WHM, you have effectively compromised every customer who shares that box.

The exposure was massive. Rapid7 ran a Shodan scan and found roughly 1.5 million cPanel instances directly reachable from the internet. Every cPanel after version 11.40 was affected, which is to say practically all of them. W3Techs has cPanel as the most widely deployed web hosting control panel in the world. Coverage estimates put 70 million-plus websites under cPanel-managed servers.

And it was already being exploited. KnownHost's CEO Daniel Pearson stated publicly that his company had logged execution attempts as early as February 23, 2026, more than 60 days before the advisory. The CVSS score of 9.8 is one of those rare cases where the number actually feels conservative.

The technical story (and why it stings)

Sina Kheirkhah at watchTowr did the kind of vulnerability research that always teaches you something. When the emergency patch shipped, he pulled both the old and patched versions and diffed them. Three files changed: Cpanel/Session.pm, Cpanel/Session/Load.pm, Cpanel/Session/Encoder.pm. Inside Session.pm, one function had been moved. A function called filter_sessiondata, designed to strip dangerous characters out of session data, had been moved into saveSession, the function that writes session files to disk.

That function existed already. It had existed for years. It had been written specifically to prevent injection into session files. It just was not being called from inside saveSession. Every other code path was expected to remember to call it first. One code path inside cpsrvd, the cPanel service daemon, never did.

If you have ever stared at a security defect that turned out to be "the right code, in the wrong place, for years," you know how this feels.

How the exploit chain runs

When cpsrvd processes a login attempt, it does something that surprises a lot of people: before it checks whether the credentials are correct, it writes a pre-authentication session file to disk. This is how cPanel keeps state across multiple HTTP requests during a login flow. The file goes to /var/cpanel/sessions/raw/ and stores things like the originating IP, an assigned security token, and whether 2FA has been verified.

The format is exactly what you would expect from a Perl-rooted codebase. One property per line, key equals value:

local_ip_address=172.17.0.2
needs_auth=1
tfa_verified=0
ip_address=172.17.0.1

The attack relies on CRLF injection. CRLF is the carriage-return / line-feed pair, written in code as \r\n, which signals a new line on most systems. In a session file where each line is a separate property, injecting \r\n means injecting a new property. If you can land those characters into something the server writes to that file, you can inject any property you want, including user=root, hasroot=1, and tfa_verified=1.

A second problem made the first one exploitable. When the session cookie is sent without its per-session encryption secret, cpsrvd skips the encoding of the password field entirely and writes it to the session file as raw plaintext. Unsanitised input plus no encoding gave attackers a clean write primitive into the session file.

The exploit chain is short:

  1. Send a deliberately failed login. cpsrvd writes the pre-auth session file and returns 401, but importantly returns a session cookie.
POST /login/?login_only=1 HTTP/1.1
Host: target:2087
Content-Type: application/x-www-form-urlencoded
user=root&pass=wrong
  1. Read the cookie that comes back. The value after the comma is the per-session encryption secret.
Set-Cookie: whostmgrsession=:Wg_mjzgt1hyfXefK,1bd3d4bf5ecbf83b660789ab0f3198fa
  1. Send the cookie back without the secret. With the encryption key gone, cpsrvd writes the password field as plaintext. Load that field with CRLF-separated fake session properties via the Authorization header:
Authorization: Basic [base64 of: root:x\r\nhasroot=1\r\ntfa_verified=1\r\nuser=root\r\ncp_security_token=/cpsess999999999]

When cpsrvd reloads the session file, it reads user=root, hasroot=1, and tfa_verified=1 as legitimate session properties. The session is now a fully authenticated root session. Two-factor authentication is marked as already verified. No password was ever checked.

The patch moved filter_sessiondata into saveSession directly, so sanitisation happens regardless of which code path called the function, and added handling for when the per-session encryption key is missing. The patch took two to three hours to ship after the advisory went out. The exploitation window was 64 days.

What the hosters did, in real time

The hosting industry's reaction is the part that should stick with anyone who runs shared hosting infrastructure. Within hours of the advisory, Namecheap, KnownHost, HostPapa, InMotion, and hosting.com blocked access to cPanel and WHM ports across their own infrastructure. They locked their own paying customers out of their own control panels. Namecheap had the patch applied by April 29 at 02:42 UTC.

Picture the call you have to make to a customer to explain that, yes, they cannot log in to their cPanel right now, no, that is not a billing issue, no, you cannot give them a workaround, and the reason is that their alternative is being compromised in real time. The hosters who locked everyone out are the ones who got it right. The ones who tried to "patch in place without disruption" are the ones whose names will show up in incident reports later.

CISA added the CVE to its Known Exploited Vulnerabilities catalog on April 30, 2026, with a May 21 deadline for federal civilian agencies. On April 29, watchTowr published a full technical breakdown alongside a working PoC. Once that lands, the gap between disclosure and mass exploitation closes. Anyone with a Shodan query and the PoC can scan and hit 1.5 million exposed instances.

What you do right now if you run cPanel

Every cPanel after 11.40 was vulnerable, and 11.40 is old enough that practically every active install fell in scope. The practical playbook:

  1. Check your version: cat /usr/local/cpanel/version
  2. Update: /scripts/upcp --force
  3. Restart cpsrvd: /scripts/restartsrv_cpsrvd
  4. If you cannot patch right now, block ports 2083, 2087, 2095, and 2096 at the firewall.
  5. If port-blocking is not an option, stop cpsrvd and cpdavd.
  6. Run cPanel's official IOC detection script regardless of when you patched.

Patched versions per release track:

11.86.0.x   to 11.86.0.41
11.110.0.x  to 11.110.0.97
11.118.0.x  to 11.118.0.63
11.126.0.x  to 11.126.0.54
11.130.0.x  to 11.130.0.19
11.132.0.x  to 11.132.0.29
11.134.0.x  to 11.134.0.20
11.136.0.x  to 11.136.0.5

WP Squared customers need 136.1.7 or later.

If your server was running an unpatched version at any point between February 23 and the day you patched, treat it as potentially compromised and look for the indicators cPanel's IOC script flags: pre-authentication session files containing user=root or other authenticated properties, sessions where a login was rejected but an authenticated security token was nonetheless written. WatchTowr also released a Detection Artifact Generator that checks whether a host is still vulnerable.

For shared-hosting providers: assume the blast radius. If a single tenant on your server reports something odd in their account, do not treat it as a single-tenant problem. The compromise model here is "compromise of one cPanel server equals compromise of every customer on that server."

What practitioners should take from this

A few things worth sitting with after this one.

The vulnerability was a missed function call. filter_sessiondata already existed. The defence had been written, tested, and shipped. It was not being invoked from one specific code path. That is not a class of bug you find by adding more security tools. You find it by reading code, diffing patches, or treating session-file write paths as a security boundary worth modelling end to end.

Pre-authentication code paths are security boundaries. A lot of teams treat anything before the credential check as "the part where we set up the request" and apply less scrutiny than the post-auth code. CVE-2026-41940 is a working demonstration that the pre-auth path can leak more authority than the post-auth path. If your software writes anything to disk before authentication completes, that write needs the same review your post-auth handlers get.

Vendor "nothing is wrong" responses cost real time. The exploitation window was 64 days. The disclosure window was at least two weeks. The patch shipped in two to three hours after the advisory went out. The bottleneck was not engineering. It was the gap between "researcher reports something" and "vendor accepts it is a real bug." If your incident-response process for inbound vulnerability reports defaults to "we have not seen this exploited so it is probably nothing," your timeline is going to look like this one.

Shared hosting still trades security boundaries for convenience. The reason cPanel and WHM exist at all is to let one operator manage many tenants on one server through a friendly web interface. That model is a deliberate trade-off, and most of the time it works fine. When it does not, the blast radius is the entire host. Anyone choosing shared hosting for a workload should know that they are choosing the security posture of the worst-patched neighbour on the box.

Diff-based vulnerability research keeps producing. Kheirkhah's path here was the same one that has produced a long list of public exploits in the last few years. Patch ships, attacker-aligned researcher diffs the patch, full exploit lands within hours or days. If you are operating software with a patch cycle, you should assume that any patch you ship is teaching attackers how to write the exploit you just blocked. That changes how you think about staged rollouts and emergency patching.

I have run /scripts/upcp more times than I can count, and most of the time the cPanel folks have done solid work. This one is going to be on the shortlist of cPanel CVEs that practitioners reference when they argue about disclosure timelines and shared-hosting risk. The lesson is not that cPanel is uniquely bad. The lesson is that a sanitisation function that already exists is worth zero unless it is called from every code path that needs it, and the cost of finding out which code path skipped the call is sometimes 64 days of root access on 1.5 million servers.

If you run a cPanel box, patch it tonight. Then go look at your own software for filter_sessiondata-shaped gaps.

Sources and credits

The original technical drop on CVE-2026-41940 came from Sina Kheirkhah (@SinSinology) at watchTowr Labs. His patch-diff analysis, the four-step exploit chain reconstruction, and the working proof-of-concept are the foundation that every other writeup on this CVE (including this one) is built on. If you read one thing on this vulnerability, read his.

Primary source:

Supporting reporting and context:

  • Rapid7 for the emergency threat-response writeup and the Shodan scan that put the internet-exposed population at roughly 1.5 million instances.
  • Help Net Security for confirming and contextualising the in-the-wild exploitation timeline (cPanel zero-day exploited for months before patch release).
  • Daniel Pearson, KnownHost CEO for publicly stating that his company logged execution attempts as early as February 23, 2026, which is what established the 64-day pre-disclosure exploitation window.
  • Webhosting.today for reporting the disclosure-timeline details, including cPanel's initial response that nothing was wrong.
  • W3Techs for the cPanel deployment-share statistics that put the affected population in context.
  • CISA for adding CVE-2026-41940 to the Known Exploited Vulnerabilities catalog on April 30, 2026, with a May 21 federal civilian agency remediation deadline.
  • The hosting providers who took the pain of locking their own customers out of their own control panels rather than watch the customer base get compromised: Namecheap, KnownHost, HostPapa, InMotion, hosting.com.

Practitioner-friendly synthesis:

  • Jolanda de Koff at HackingPassion.com wrote a readable practitioner writeup of the watchTowr findings. Her piece served as one of the source briefs for this post and is worth reading if you want the technical detail in narrative form rather than the lab-report style.

This post is a practitioner reaction, not original research. The CVE itself, the patch diff, the exploit chain, and the public PoC are watchTowr's work. Everything else here is commentary on top of their work.

Subscribe to Basic Security

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
[email protected]
Subscribe