CWP2Shell: a ten-vulnerability chain roots more than 118,000 Control Web Panel hosts
On November 3, 2026, VulnCheck disclosed ten vulnerabilities in Control Web Panel (CWP) that chain from an unauthenticated request to a root shell, with 118,000 instances observed online. Hosting providers should move to version 1.29 and take ports 2083, 2031, and 2087 off the public internet.
November 3, 2026. VulnCheck publishes a disclosure of ten vulnerabilities in Control Web Panel (CWP), the hosting panel formerly known as CentOS Web Panel, under the title “CWP2Shell: The Login Page That Never Says No”. November 3, 2026, same day. The author, Valentin Lobstein (Chocapikk), documents a complete chain: an unauthenticated request reaches code execution, then two independent paths lead to a root shell. November 3, 2026, again. VulnCheck Target Intelligence counts 118,151 CWP service observations, 19,834 on the 2083 user-panel port alone. The headline fits in one line: a control panel’s front door, meant to say “no”, keeps working after it has answered.
For a hosting provider running dozens of customer sites behind a single panel, this is not one more CVE. It shows that the boundary between a low-privileged user and super-user actions was one missing keyword thick.
The entry point: a redirect that stops nothing
CWP exposes its user panel on port 2083. The login page, shared by all accounts, returns a 302 redirect to the sign-in screen when you request a dashboard without authenticating. The flaw is right there: behind that redirect, there is no exit(). The request falls through and includes a module whose name the attacker controls.
A module here is just one of the panel’s feature pages — the php.ini editor, the file manager — that the dashboard pulls in by name to render a section. CVE-2026-73695, the opening flaw, is an unauthenticated local file inclusion through path traversal on the module parameter (CWE-98). CVE-2026-73696 describes the execution-after-redirect itself (CWE-698). Once the module is reached, two lids lift: CVE-2026-73697 writes an arbitrary file and injects a command via phpini_editor, and CVE-2026-77876 injects a command in the protected_directory module (CWE-78), the sink that passes input straight into shell_exec.
At that point the attacker runs code as the hosting user. That is the entry. The escalation comes next.
The escalation: a root API on loopback
CWP runs a small service called the user API on 127.0.0.1:2302, as root, talking to MySQL as root@localhost. It is meant to be protected by a token gate. Two cracks get around it.
- CVE-2026-77877: token enforcement is missing on several root-API routes — they stay reachable with no authentication (CWE-306).
- CVE-2026-77879: a SQL injection in the
access_token()gate forges past the authentication check (CWE-89).
Behind those two cracks, three command injections run as root: CVE-2026-77878 on /v1/restoredatabase/, CVE-2026-77880 on /v1/newpass/, and CVE-2026-104080 on /v1/valid_token/, where the raw user value reaches a root-owned grep command. CVE-2026-77881, a blind SQL injection on /v1/user_panel_dashboard/, reads the whole database as MySQL root.
Chained together, one host address and one hosting-account name yield a root shell — CVSS 10.0 once the scope change is counted. VulnCheck validated the chain on a CWP7 webpanel 1.8 build running AlmaLinux 9, a build that already carried the fix for the old CVE-2025-48703.
A recurrence, not a novelty
Unauthenticated-to-RCE in CWP is not a new category. CVE-2025-48703, a command injection in the filemanager module, was flagged as exploited by VulnCheck KEV on August 15, 2025, then mass-exploited within days of a public exploit, before reaching CISA KEV on November 4, 2025. The mechanism was the same: the panel’s dispatch reaches a module before anyone authenticates, and that module runs request input in a shell.
The irony is precise: the 1.8 build VulnCheck tested returns a 403 to the published exploit for 48703 — and still runs a command through the module next door. The previous fix was point-specific; the bug class stayed.
What to do now
The fix exists: all ten flaws are closed in CWP 1.29, released October 31, 2026, in stages — 1.12 closes the pre-auth entry, 1.16 the user-panel modules, 1.27 and 1.29 the root API. The current recommended release is 1.30.
- Move to 1.29 or later. This is the only action that closes the whole chain. Check the actual version of each panel, not just the changelog.
- Take the panel ports off the internet. Keep 2083 (user), 2031, and 2087 (admin) behind an allowlist or a VPN. Even when patched, a control panel has no business being public.
- Audit hosting accounts. A single valid account name is enough for entry on builds before 1.12; review accounts and their access.
- Watch the loopback. Any anomalous request toward the service on
127.0.0.1:2302is a signal of an escalation in progress.
The update is not optional: on a build before 1.12, one account name is enough to reach root without authentication.
Verdict
The flaw is not a single clumsy line of code; it is an authentication boundary reduced to one missing keyword, replicated between the user panel and the root API. If you run a CWP panel, move to 1.29 or 1.30 now and cut ports 2083/2031/2087 off the internet — an exposure of more than 118,000 instances guarantees automated exploitation will follow the disclosure. If you host for third parties, the lesson is broader: a control panel is a machine for performing privileged actions on behalf of low-privileged users, and any gap in its boundary flips every primitive to the wrong side at once. The question is not whether these panels will be attacked, but how many of them will keep saying “no” without stopping.