Skip to content

Back to the catalog

CVE-2026-41940: cPanel & WHM Pre-Auth RCE — Two Write Paths, One Filter
exploit-intel.comwriteup

CVE-2026-41940: cPanel & WHM Pre-Auth RCE — Two Write Paths, One Filter

Detailed exploit-chain analysis of CVE-2026-41940, a pre-auth CRLF injection in cPanel/WHM's Perl session subsystem (Cpanel/Session.pm) that lets an unauthenticated attacker inject arbitrary session keys via a crafted Basic-Auth password, bypass the truthy-only auth gate, and reach root via the hardcoded-root importsshkey/authorizesshkey WHM admin APIs. The piece walks through six unauthenticated HTTP requests to root SSH access on an unpatched lab, explains why an existing filter_sessiondata validation function wasn't applied to the vulnerable write path, evaluates what the April 28 patch did and didn't fix (including an unpatched sibling primitive in LocalMySQL.pm and a near-miss in Features/Write.pm), and provides detection queries plus a Python PoC.

TL;DR Full chain writeup of CVE-2026-41940: CRLF injection in cPanel/WHM session file promotes attacker-controlled keys to bypass auth and reach root via hardcoded-root SSH-key WHM APIs.
Document

What it is

CVE-2026-41940, a CVSS 9.8 pre-auth root RCE in cPanel & WHM, patched 2026-04-28. The summary has the mechanism; what it lacks is the version boundaries, the detection commands, the exploitation preconditions, and what the patch actually changed.

Preconditions / Affected

Fixed in cPanel & WHM 11.110.0.97, 11.118.0.63, 11.126.0.54, 11.132.0.29, 11.134.0.20, 11.136.0.5, and WP Squared 11.136.1.7. Anything prior is vulnerable. Four real-world frictions the page documents (none of which prevent the attack):

  • WHM must be reachable. Port 2087 is often firewalled or fronted by a permissive proxy at /whm; the exploit only helps if you can reach cpsrvd.
  • cpHulk rate-limits /login/ per source IP (one failed login per exploit run; rotate IPs ~every 5 attempts). It does not observe post-bypass admin-API calls.
  • Session is bound to source IP — CGNAT / rotating egress causes DEFERRED LOGIN failures. Needs stable egress.
  • Licensing gate — an unlicensed install accepts the bypass but API handlers return "Cannot Read License File." Any production (paid/trial) box runs the SSH-key APIs fine.

What it buys the attacker

679 admin APIs reachable by the bypassed session; ~120 counted as RCE-class. Full access to every cPanel/reseller account on shared hosting, plus lateral-movement primitives (execute_remote_whmapi1_with_password, create_remote_root_transfer_session, legacy accesshash tokens not cpHulk-rate-limited).

What to do

Patch. Then, before anything else, hunt for prior compromise:

grep -l '"pass":"x"' /var/cpanel/sessions/cache/* | xargs -r grep -l 'successful_internal_auth_with_timestamp'
ssh-keygen -lf /root/.ssh/authorized_keys

Also check /var/cpanel/sessions/raw/ for embedded \r in non-origin fields (multiple physical lines with \r values = injection footprint); check login_log for FAILED LOGIN ... method=badpass followed by repeated DEFERRED LOGIN ... security token missing from one IP within seconds; and compare mtimes of matching raw/<id> and cache/<id> files — a raw file substantially newer than its cache is an injected-but-not-yet-promoted session. Once root, an attacker can erase all of these, so treat any unpatched box as compromised rather than expecting evidence.

Caveats

The patch touched only three files (Session.pm, Session/Load.pm, Session/Encoder.pm) and works by hex-wrapping the pass field when $ob is undef — it does not move filter_sessiondata to the second write path. The underlying structural weaknesses are byte-identical in 11.134.0.20: the truthy-only auth gate (any successful_*_auth_with_timestamp key, unsigned, no HMAC/freshness check), eight hardcoded-root API handlers (including a setmysqlpasswd→UDF path in LocalMySQL.pm that gives the same root shell via two calls), and a latent CRLF footgun in Features/Write.pm (strips \r, collapses but does not remove \n). The vendor-recommended durable fix — HMAC session contents on save and reject on load — is not present. The authors verified the chain end-to-end against an 11.134.0.19 lab and confirmed the patched 11.134.0.20 build returns 403 at step 4.

CVEs named here

Technologies named here

Techniques named here

  • CRLF injection in session pass field
  • Two-write-path filter bypass
  • Truthy auth gate bypass
  • Session key promotion via read-modify-write
  • Security token rotation suppression via needs_auth=0
  • Hardcoded-root WHM API abuse
  • MySQL root password reset to native code execution
  • Lateral movement via WHM admin APIs post-bypass