Bali, Indonesia
Insights

Blocked Ports 2083 and 2087, but cPanel Service Subdomains Still Expose Login

November 1, 2026
0:00
When a cPanel advisory lands and exploitation is already happening, a common first move is to block ports 2083 and 2087 at the firewall. It feels like it takes cPanel and WHM off the internet. Then someone opens https://whm.example.com in a browser and the WHM login page loads anyway. The firewall rule is fine. The request simply came in through a different door. This matters most during incidents like CVE-2026-41940, the session-handling authentication bypass in cPanel & WHM. According to the advisory context, active exploitation pushed many providers to temporarily restrict ports like 2087 and 2083 until patches were deployed. If the login surface is still reachable through ports 80 and 443, that restriction protects less than people think.
The usual pattern looks like this. The firewall (CSF, firewalld, iptables, or an upstream network ACL) drops inbound TCP 2083 and 2087. A quick test confirms it: https://server-ip:2087 times out. So far, so good. But https://cpanel.example.com and https://whm.example.com still return a working login form, on the standard HTTPS port, with a valid certificate. Sometimes webmail.example.com works too. To someone who just closed the admin ports, this looks like the firewall is being ignored. It isn't. Those hostnames are service subdomains, which cPanel's documentation has also called proxy subdomains. They exist so users on restrictive networks (offices, hotels, schools) that only allow 80 and 443 outbound can still reach cPanel, WHM, and webmail.
cPanel and WHM are served by cpsrvd, cPanel's own daemon, listening on ports such as 2082/2083 (cPanel), 2086/2087 (WHM), and 2095/2096 (webmail). The public web server on 80 and 443 is a separate process, usually Apache, sometimes LiteSpeed or cPanel's Nginx, depending on how the server is built. When proxy subdomains are enabled, the web server has rules that match hostnames like cpanel.*, whm.*, and webmail.*. A matching request is forwarded internally to cpsrvd on the right port. The flow is:
  1. The client connects to the server's public IP on port 443 with Host: whm.example.com.
  2. The web server accepts it, because 443 is open for normal websites.
  3. The web server opens its own connection to cpsrvd on the WHM port, over the loopback or local interface.
  4. cpsrvd answers, and the response goes back to the client through the web server.
Step 3 is the root cause. A typical firewall rule blocking 2087 filters inbound traffic from the internet on the public interface. The proxied connection never crosses that path. It starts on the server itself, so the rule never sees it. From the firewall's point of view, all that happened was ordinary HTTPS traffic to port 443. The same logic applies to an upstream network firewall or cloud security group. Those only see the outside connection to 443.
Before concluding it is the proxy path, a few other explanations come up often enough to eliminate first. The firewall rule might not be active. A CSF config edited but not restarted, or a firewalld rule added without --permanent and lost on reload, will leave the ports open. Test the direct port from an outside machine, not from the server itself, because local tests often bypass the rule. The browser might be showing a cached page. A login form rendered from cache proves nothing. Use curl from a clean shell so there is no cache or saved session involved. The DNS records might seem like the problem. People sometimes delete the cpanel, whm, and webmail A records and consider the issue solved. That helps against casual discovery, but it does not remove the proxy rules. The web server routes by the Host header and TLS SNI, not by whether DNS exists. Anyone who knows the server IP can send Host: whm.example.com directly, and if any hosted domain still resolves those names, the path is still public. Other cPanel ports may still be open. Blocking only 2083 and 2087 leaves 2082, 2086, 2095, and 2096 to whatever the firewall already allowed. What each one serves depends on version and settings, so check them rather than assuming they redirect harmlessly.
Run these from a machine outside the server's network. curl --resolve pins a hostname to a specific IP, so you can test the proxy path even if DNS records are gone or point elsewhere. Replace 203.0.113.10 with the server's public IP and example.com with any domain hosted on it.
BASH
# Direct ports: should time out or be refused if the firewall works
curl -skI --max-time 10 https://203.0.113.10:2087/
curl -skI --max-time 10 https://203.0.113.10:2083/

# Proxy path on 443, forcing the hostname to the server IP (bypasses DNS)
curl -sk -o /dev/null -w '%{http_code}
' --resolve 'whm.example.com:443:203.0.113.10' https://whm.example.com/
curl -sk -o /dev/null -w '%{http_code}
' --resolve 'cpanel.example.com:443:203.0.113.10' https://cpanel.example.com/
curl -sk -o /dev/null -w '%{http_code}
' --resolve 'webmail.example.com:443:203.0.113.10' https://webmail.example.com/

# Look for login markup instead of trusting the status code alone
curl -sk --resolve 'whm.example.com:443:203.0.113.10' https://whm.example.com/ | grep -i -m 3 'login'
A timeout on the direct ports combined with a 200 and login markup on the subdomains is the signature of this problem. Status codes alone can mislead, since a redirect or a generic error page can return 200 too, so check the body. On the server, confirm the setting rather than guessing from behavior. The Tweak Settings value is stored in /var/cpanel/cpanel.config, and whmapi1 can read it:
BASH
# Read-only checks; 1 usually means proxy subdomains are enabled
grep -E '^proxysubdomains' /var/cpanel/cpanel.config
whmapi1 get_tweaksetting key=proxysubdomains
If you want to see whether the proxy path is being used, look at cpsrvd's own logs. Proxied requests show up there, but the source IP recorded for them depends on how the proxy passes client addresses on your build, so verify what you see before drawing conclusions.
BASH
# Recent login attempts and WHM requests seen by cpsrvd
tail -n 50 /usr/local/cpanel/logs/login_log
grep -c 'GET /' /usr/local/cpanel/logs/access_log
If proxied requests appear with a local address, IP-based allow lists on cpsrvd may treat them differently from direct connections. That is one more reason not to rely on the port block alone.
The direct fix is in WHM under Tweak Settings, in the domain-related section, where the proxy subdomains option can be turned off. A related option controls whether users can override the automatically generated proxy subdomains with their own records. Labels and placement shift between versions, so search Tweak Settings for "proxy" rather than relying on a fixed path. Turning it off has side effects worth weighing, especially during an incident when you want to avoid surprise tickets:
  • Users who bookmark cpanel.theirdomain.com or webmail.theirdomain.com will lose that shortcut.
  • Users on networks that block high ports will lose access to cPanel and webmail entirely until the restriction is lifted.
  • Email client autodiscovery and some calendar or contacts setups may depend on related subdomains. Test a mail client after the change.
Support teams tend to get the webmail complaints first, so it helps to tell customers in advance that webmail on the custom ports or via the hostname is the temporary path. If disabling it entirely is too disruptive, the alternative is restricting it at the web server, for example allowing the service-subdomain hostnames only from an office VPN or a short list of IPs. How to do that depends on whether Apache, LiteSpeed, or Nginx is in front and on how cPanel generates its config, so make the change in cPanel's supported include files rather than editing generated configs that get overwritten on rebuild. For the broader question of firewall versus Host Access Control for WHM, see Should You Restrict WHM Ports with Host Access Control or a Firewall?. After any change, rerun the curl --resolve tests from outside. The proxy path is closed only when those requests no longer return a cPanel or WHM login page, regardless of what Tweak Settings says. None of this replaces patching. The research context for CVE-2026-41940 points to fixed builds above versions such as 11.136.0.5 and 11.134.0.20, depending on release tier, plus official scripts to check historical session files for signs of compromise. Blocking access buys time; it does not tell you whether someone got in before the block. Patched cPanel for CVE-2026-41940? That Doesn't Prove the Server Wasn't Breached covers that part. The practical rule: when you shut the admin ports during an incident, treat ports 80 and 443 as a second entrance to the same login. Test both paths from outside with a pinned hostname, disable or restrict proxy subdomains for the duration, tell users which access path still works, and keep the restriction until the server is patched and checked for compromise.