## https://sploitus.com/exploit?id=E414FD2C-33F9-560F-A367-198FB076252F
=============================================================================
CVE-2026-41940 - cPanel & WHM Authentication Bypass Exploit
=============================================================================
Vulnerability: Session-file manipulation through CRLF injection in cpsrvd's
HTTP Basic authentication handler
CVE: CVE-2026-41940
CVSS: 9.8 (Critical)
CWE: CWE-93 (CRLF Injection) / CWE-306 (Missing Authentication)
Affected: cPanel & WHM versions prior to:
11.110.0.97, 11.118.0.63, 11.126.0.54,
11.132.0.29, 11.134.0.20, 11.136.0.5
Ports: 2082/2083 (cPanel), 2086/2087 (WHM), 2095/2096 (Webmail)
TECHNICAL ROOT CAUSE:
cpsrvd's HTTP Basic auth handler stores the supplied password verbatim
into the pre-authentication session file via Cpanel::Session::saveSession()
-- bypassing the sanitising Cpanel::Session::create() /
Cpanel::Session::Modify::save() wrappers, which call filter_sessiondata()
to strip CR/LF. Because saveSession() itself does not call
filter_sessiondata(), any CR/LF in the password is written to the raw
session file as literal newlines.
When a request is rejected for failing the URL-bound security-token check,
cpsrvd's do_token_denied() handler invokes
Cpanel::Session::Modify::new($session, nocache => 1). The nocache => 1
flag forces a re-parse of the raw session file (line-by-line key=value)
instead of loading the JSON cache. CRLF-split lines from the attacker-
controlled pass field are now treated as separate key=value records.
Modify::save() then rewrites the JSON cache with all parsed keys --
including the attacker's -- promoted to top-level session entries.
After the regen, the session contains user=root, hasroot=1,
tfa_verified=1, an attacker-chosen cp_security_token, and a fresh
successful_internal_auth_with_timestamp. cpsrvd treats the session as
fully authenticated.
ATTACK CHAIN (4 HTTP requests):
1. Pre-auth session mint: POST /login/?login_only=1 (failed login)
-> creates session file, get whostmgrsession cookie
2. CRLF injection: GET / with Authorization: Basic header containing
CRLF payload, cookie WITHOUT obfuscation suffix
-> password with embedded \r\n written to raw session file
3. Regen trigger: GET /cpsess/scripts2/listaccts
-> do_token_denied() fires, re-parses raw file, promotes injected keys
4. Authenticated access: GET /cpsess/json-api/version
-> session now has root privileges, bypasses password & 2FA
NOTE: There is a race condition due to Perl's randomized hash iteration
order. The original (unset) cp_security_token may overwrite the injected
one. Multiple retries make the chain reliable.
DISCLAIMER: This tool is provided for authorized security testing and
research purposes only. Unauthorized use against systems you do not own
or have explicit permission to test is illegal.