CyberBytes Daily

Trending cyberattacks, explained simply.

critical vulnerability

How a missing function call let attackers bypass authentication on 1.5 million web hosting control panels

A sanitization function existed in cPanel's codebase for years. It was designed to strip dangerous characters before writing session data to disk. It was never called in the one place that mattered. That single omission let attackers forge a root-level administrator session on any cPanel server, with no valid password and no brute force required, by embedding a few extra characters in a login request.

The vulnerability, CVE-2026-41940, carries a CVSS score of 9.8 out of 10. cPanel and WHM collectively manage more than 70 million domains across roughly 1.5 million internet-exposed servers. When the emergency advisory dropped on April 28, 2026, the industry response was immediate and blunt: within hours, nearly every major hosting provider on the planet had firewalled their own customers off from their own control panels. Millions of website owners temporarily lost access to their hosting dashboards because the alternative was leaving attackers a direct path to root.

What makes this worse: exploitation was already happening. KnownHost confirmed active attacks as early as February 23, 2026, meaning attackers were using this zero-day for at least 64 days before a patch existed. The vendor was reportedly told about the vulnerability approximately two weeks before the public advisory and initially responded that nothing was wrong.

Narrative Β· 6 min read

The Context

cPanel and WHM (Web Host Manager) are the dominant control panel software for shared web hosting. When you log into a hosting dashboard to upload files, manage email, or configure a database, there is a good chance you are using cPanel. WHM is the administrative layer above it: the interface hosting companies use to manage entire servers and provision accounts for their customers. Together, they run on an estimated 1.5 million internet-exposed servers and underpin more than 70 million domains worldwide.

The software is made by WebPros International. Because cPanel and WHM sit at the management layer of shared hosting infrastructure, a single compromised server does not mean one victim. It means every website, every database, every email account, and every end user hosted on that server is simultaneously exposed.

The Attack, Phase by Phase

Phase 1: Minting a Pre-Authentication Session

The attack begins with a deliberate failed login. The attacker sends a request to the WHM login endpoint on port 2087 with an intentionally wrong password. cPanel's design creates a problem here: before it validates whether the password is correct, cpsrvd writes a new session file to disk at /var/cpanel/sessions/raw/ and sends back a session cookie called whostmgrsession.

The attacker then strips a portion of that cookie value, keeping only the raw session identifier. This stripped cookie bypasses an encryption step that would normally be applied to attacker-controlled values in later requests. The attacker now holds a key to a session file they are about to manipulate.

ATTACKER TRIGGERS PRE-AUTH SESSION CREATIONπŸ”‘1Send deliberate failed loginPOST to WHM port 2087, wrong passwordπŸ“„2cpsrvd writes session fileSaved to /var/cpanel/sessions/raw/πŸͺ3Server returns session cookiewhostmgrsession cookie issuedβœ‚οΈ4Attacker strips cookie segmentBypasses encryption on attacker valuesAuthentication has not yet occurred. The session file already exists on disk.

Phase 2: Injecting Fake Session Records

The attacker sends a second request using HTTP Basic Authentication, a standard login method where credentials are encoded in a request header. The password field of that header contains a crafted payload: the real password value, followed by raw newline characters, followed by a series of fake session properties.

The properties injected include hasroot=1, tfa_verified=1, user=root, a forged security token, and a flag called successful_internal_auth_with_timestamp set to a plausible Unix timestamp.

Here is the flaw: cPanel's set_pass() function, which processes the password field, strips null bytes but does not strip newline characters. A sanitization function called filter_sessiondata existed in the codebase specifically to handle this, but it was never called inside the saveSession function itself. Every caller was expected to invoke it manually. The critical code path in cpsrvd simply did not. The result: those injected lines are written verbatim into the session file as if they were legitimate session properties.

CRLF INJECTION INTO SESSION FILEπŸ§ͺ1Craft malicious Basic Auth headerPassword contains \r\n-separated fake records⚠️2set_pass() strips null bytes onlyNewline characters pass through unsanitizedπŸ“3saveSession writes injected linesfilter_sessiondata never called on this pathπŸ’Ύ4Session file now contains forged keyshasroot=1, tfa_verified=1, user=root injectedThe sanitization function existed. It was just never called here.

Phase 3: Poisoning the Cache and Claiming Root

cpsrvd normally reads session state from a JSON cache file, not the raw text file written in Phase 2. The attacker's final move forces a cache refresh. By sending a third request deliberately without a valid security token, the attacker causes cpsrvd to fall back to reading the raw text file and then re-serialize its contents back into the JSON cache.

From that point forward, every request to the server sees the forged values as legitimate session properties. The successful_internal_auth_with_timestamp flag tells cpsrvd to skip password validation entirely and return AUTH_OK unconditionally. The tfa_verified=1 flag suppresses any two-factor authentication (2FA) challenge. The attacker now holds a fully authenticated root-level WHM session. No valid password was ever provided.

CACHE POISONING AND SESSION TAKEOVERπŸ”„1Send request without security tokenForces cpsrvd to re-read raw session file☠️2Raw file flushed into JSON cacheInjected values now permanent in cache🚫3AUTH_OK returned unconditionallyTimestamp flag skips password check🚫42FA challenge suppressedtfa_verified=1 bypasses second factorπŸ‘‘Full WHM root accessNo password. No 2FA. No brute force.2FA provided zero protection against this attack.

Phase 4: Post-Exploitation

With root-level WHM access, the attacker can read every customer hosting account on the server, modify files and databases, create backdoor accounts, install web shells (hidden scripts that allow persistent remote access), deploy malware, steal credentials, and pivot into customer networks. Because cPanel manages shared hosting infrastructure, a single compromised server can expose thousands of downstream websites and their end users simultaneously.

POST-EXPLOITATION BLAST RADIUSπŸ”“1Read all customer accountsEvery hosted site, database, email exposedπŸ•ΈοΈ2Install web shellsPersistent backdoor access to serverπŸ”‘3Create backdoor WHM accountsSurvives password resets on other accounts🌐4Pivot into customer networksCredentials harvested from hosted databasesOne server. Thousands of victims.

What Made This Possible

  1. A convention treated as a contract. The filter_sessiondata function existed and worked. But it was designed as something callers were expected to invoke, not something the save operation enforced automatically. When one code path skipped it, there was no safety net. A sanitization step that is optional is not a sanitization step.

  2. Writing to disk before validating identity. cpsrvd creates a session file before it knows whether the requester is legitimate. This design means attacker-controlled input reaches persistent storage during the pre-authentication phase, before any trust decision has been made.

  3. A 64-day gap between exploitation and patch. The earliest confirmed attack was February 23, 2026. The patch arrived April 28. The vendor was reportedly told about the vulnerability two weeks before the advisory and initially said nothing was wrong. That response delayed the patch window while active exploitation continued.

The systemic lesson: control-plane software managing shared infrastructure carries asymmetric blast radius. One exploited server is not one victim. It is every tenant on that server.

What Should Have Stopped This

Every defense that would have reduced the blast radius here shares one trait: it does not depend on cPanel's own authentication integrity to function.

  • Network segmentation of management ports. cPanel's management ports (2082, 2083, 2086, 2087, 2095, 2096) should not be directly reachable from the public internet. Restricting access to known IP ranges or a VPN (a private network tunnel) means an attacker cannot reach the login endpoint in the first place. Many providers violated this basic principle, which is why the emergency firewall blocks were so disruptive.
  • Vendor disclosure response. When a researcher reported this vulnerability approximately two weeks before the public advisory, the correct response was immediate triage and coordinated disclosure to hosting providers, not an assertion that nothing was wrong. That delay extended the exploitation window.
  • Faster patch deployment pipelines. Full deployment across major providers took 6 to 7 hours from the initial advisory. For a CVSS 9.8 vulnerability with active zero-day exploitation, that window is significant. Providers with automated patch deployment closed it faster.

The Takeaway

CVE-2026-41940 is not a story about a missing feature. It is a story about a safety function that existed, worked, and was simply never called in the one place it needed to be. The gap between "the code exists" and "the code runs" is where this attack lived for years.

This is the same class of failure as the Axios supply chain attack: a trust boundary that looked enforced from the outside but had a gap the attacker could walk through. In the Axios case, the boundary was package integrity during installation. Here, the boundary was session data integrity during write. In both cases, the defense existed in the codebase. It just was not applied at the moment it mattered.

Pattern to remember: A sanitization function that is optional is not a sanitization function. Safety checks must be enforced at the boundary where untrusted data is committed to storage, not delegated to callers who may forget.

What changed: Authentication can be bypassed not by attacking the login check itself, but by poisoning the session record that the login check reads, before the check ever runs.

Technical Deep Dive Β· 4 min

The Technical Mechanism

CVE-2026-41940 is a CRLF injection vulnerability in cpsrvd, the cPanel service daemon, rooted in the pre-authentication session creation phase. The flaw exists at the intersection of two design decisions: session files are written to disk before authentication is validated, and the saveSession function does not internally enforce sanitization of the data it persists.

Session file format: cPanel stores session state in newline-delimited key=value files at /var/cpanel/sessions/raw/. Each property occupies its own line. The format is inherently vulnerable to CRLF injection: any unsanitized newline in a value becomes a new top-level record.

Root cause: The set_pass() function, which processes the password field from a decoded HTTP Basic Authorization header, strips only null bytes (\0). It does not strip \r or \n. A sanitization function, filter_sessiondata, existed in the codebase and was designed to handle this class of input. However, it was never called inside saveSession itself. The design assumed every caller would invoke filter_sessiondata before calling saveSession. The Basic Auth code path in cpsrvd did not. The patch moves the filter_sessiondata call inside saveSession directly, enforcing sanitization at the write boundary regardless of caller behavior.

Full exploit chain:

  1. Attacker sends POST /login/?login_only=1 to port 2087 with an incorrect password. cpsrvd mints a pre-auth session at /var/cpanel/sessions/raw/ and returns a whostmgrsession cookie. Attacker strips the obfuscation segment (the portion after the comma) from the cookie value, retaining the raw session ID. This stripped form bypasses the encryption path applied to attacker-controlled values in subsequent requests.

  2. Attacker sends a second request using HTTP Basic Authentication. The password field of the decoded credential string contains: x\r\nhasroot=1\r\ntfa_verified=1\r\nuser=root\r\ncp_security_token=/cpsess9999999999\r\nsuccessful_internal_auth_with_timestamp=1777462149. Because set_pass() does not strip \r\n and saveSession does not call filter_sessiondata, these six records are written verbatim as top-level entries in the session file.

  3. Attacker sends a third request without a valid security token. This forces cpsrvd to fall back from the JSON cache to the raw text file, re-parse it, and flush the result back into the JSON cache. The injected values are now permanently present in the cache.

  4. All subsequent requests see hasroot=1, tfa_verified=1, user=root, and successful_internal_auth_with_timestamp as legitimate session keys. The successful_internal_auth_with_timestamp flag causes cpsrvd to return AUTH_OK unconditionally, skipping password validation. tfa_verified=1 suppresses any 2FA challenge. Due to Perl's randomized hash key-iteration order during session serialization, the injected cp_security_token occasionally gets overwritten by the legitimate one; a small number of retries makes the chain reliably exploitable.

CWE classification: cPanel's advisory classifies this as CWE-93 (Improper Neutralization of CRLF Sequences in HTTP Headers). Hadrian notes that CWE-117 (Improper Output Neutralization for Logs/Files) is arguably a closer fit, since the CRLF sequences land in an on-disk session file rather than an HTTP header.

TECHNICAL EXPLOIT CHAIN: CPSRVD SESSION INJECTIONπŸ“‘1POST /login/?login_only=1Port 2087, wrong password, strip cookieπŸ’‰2Basic Auth with CRLF payloadset_pass() passes \r\n; saveSession writesπŸ”„3Cache invalidation requestNo security token forces raw file re-read☠️4JSON cache poisonedhasroot=1, successful_internal_auth injectedπŸ‘‘5AUTH_OK unconditionalRoot WHM session, 2FA suppressedfilter_sessiondata existed. It was never called on this code path.

CVE and Advisories

  • CVE-2026-41940 β€” CVSS 9.8 (Critical). Assigned April 29, 2026. CISA ADP Vulnrichment tags: Automatable, Total technical impact.
  • WebPros International Security Advisory CPANEL-52908 β€” Published April 28, 2026. Describes the issue as "an issue with session loading and saving." Updated April 29 to include WP Squared v136.1.7.

Affected versions: cPanel and WHM prior to 11.110.0.97, 11.118.0.63, 11.126.0.54, 11.132.0.29, 11.134.0.20, and 11.136.0.5. All versions after v11.40 are affected. WP Squared prior to v136.1.7 is also affected. End-of-life versions received no patch.

MITRE ATT&CK Mapping

Technique IDATT&CK nameHow it appeared
T1190Exploit Public-Facing ApplicationThe attacker exploits CVE-2026-41940 in the internet-exposed cPanel/WHM login endpoint to gain unauthenticated root access.
T1134Access Token ManipulationThe attacker manipulates the whostmgrsession cookie and forges session file records to impersonate a root-authenticated user.
T1556Modify Authentication ProcessThe successful_internal_auth_with_timestamp and tfa_verified=1 injected flags subvert cpsrvd's authentication and 2FA validation logic.
T1505.003Server Software Component: Web ShellPost-exploitation: attackers with root WHM access can install web shells for persistent access to hosted websites.
T1078Valid AccountsPost-exploitation: attackers can create new backdoor WHM accounts that persist independently of password resets on other accounts.

Indicators of Compromise

The richest forensic signal is on disk. cPanel provided a detection script to scan /var/cpanel/sessions/raw/ for anomalous session files. Indicators that should never appear in a legitimate pre-authentication session include:

  • user=root in a session that has not completed authentication
  • hasroot=1 in any pre-auth session
  • tfa_verified=1 without a corresponding legitimate authentication event
  • successful_internal_auth_with_timestamp in a session file
  • Multi-line password values (any session file where the password field spans more than one line)

watchTowr Labs published a Detection Artifact Generator script to verify whether a cPanel instance is vulnerable. Because the injected session files are written to disk before exploitation completes, forensic recovery of session files from the period February 23 to April 28, 2026 may reveal exploitation attempts even on patched systems.

Network Indicators

Unexpected outbound connections from cPanel servers, new cron jobs, unauthorized SSH keys in /root/.ssh/authorized_keys, and new WHM accounts created outside normal provisioning windows.

Attribution

No specific threat actor, criminal group, or nation-state has been publicly attributed to the exploitation of CVE-2026-41940 as of April 30, 2026. KnownHost confirmed successful exploits in the wild before the patch, with the earliest confirmed attempt dated to February 23, 2026. The identity of the private researcher who disclosed the vulnerability to cPanel approximately two weeks before the public advisory is unknown, and whether that researcher is connected to the in-the-wild exploitation has not been established. No threat intelligence firm has publicly linked pre-patch exploitation to a named APT group or ransomware operator.


Primary Sources