A PBX in default configuration listens on somewhere between eight and fifteen network ports. Three of them have to face the internet for calls to work. The rest are there for your own convenience, and every one you publish is a listener that answers strangers. In June 2026 the FreeSWITCH project disclosed six advisories in a single day, and five of them needed no credentials at all. Whether that was a patch window or an incident came down to one thing: which ports were reachable.
This is not a hardening checklist you run once. It’s a question you should be able to answer in thirty seconds about any switch you operate, and most people can’t.
The three ports you actually have to publish
Start from what the job requires rather than from what the installer opened.
SIP signalling has to be reachable, because carriers and handsets need somewhere to send an INVITE. That’s 5060 on UDP and TCP, 5061 for TLS, and often 5080 for a second profile handling external traffic. RTP media has to be reachable, and that’s a wide UDP range, commonly 16384 to 32768, because every concurrent call leg needs its own pair. And your tenants need a web panel, which is 443.
That’s it. Everything else on the box is there because someone found it handy during install.

The public column is small on purpose. Everything on the right has a reason to exist and no reason to be reachable from Bulgaria.
The three public ports still need work. SIP on 5060 gets scanned constantly, so you want fail2ban watching for registration failures, per-carrier IP allow lists on your trunk profile, TLS where the far end supports it, and a hard per-tenant concurrent call cap so a compromised extension can’t run up forty thousand dollars overnight while you sleep. We wrote about the money side of that in our notes on fraud and credit controls. But those three are the cost of being a phone system. The others are optional, and treating them as optional is the whole point.
What June 2026 actually looked like
On 3 June the FreeSWITCH project published six advisories at once. ICTPBX is built on FreeSWITCH, so we read these the way you’d read a letter from your landlord. Two were rated critical, and both were pre-authentication heap buffer overflows.
CVE-2026-49841 sits in mod_verto, in the code that reads an HTTP POST body. CVE-2026-49840 sits in libesl, in the code that parses a Content-Length header. Neither one asks who you are before it starts parsing. That’s what pre-auth means, and it’s the only word in a CVE description that reliably predicts how bad your week is about to be.

Sorted by the column that matters. Severity ratings are useful for prioritising a patch queue. The login column tells you whether you can sleep before you finish patching.
The rest of the cluster fills in the picture. CVE-2026-49847 is a stack overflow in the bundled cJSON parser triggered by deeply nested JSON, which matters anywhere the switch parses JSON it didn’t write. CVE-2026-49842 turns mod_verto’s speed-test frames into a bandwidth amplifier, so your uplink pays for someone else’s flood. Two medium ones, CVE-2026-49848 and CVE-2026-49843, cover variable injection and evicting another user’s session by guessing its identifier. And three weeks earlier, CVE-2026-45771 landed a denial of service in SIP PUBLISH through XML entity expansion.
Here’s the part worth sitting with. Of those seven, exactly one is on a port you have no choice about. The SIP one. Everything else arrives over 8021 or 8082, and neither of those has any business being open to the internet.
Event Socket is a root shell with a friendlier name
Port 8021 is the FreeSWITCH Event Socket. It exists so your application layer can control the switch: originate calls, hang them up, read channel variables, subscribe to events. In ICTPBX that’s how ICTCore drives the platform, and it’s a good design. The problem is what the protocol assumes about who’s connecting.
The default password in a stock event_socket.conf.xml is ClueCon. It’s been ClueCon for over a decade. Anyone scanning port 8021 tries it first, and if it works they don’t need an exploit at all, because ESL by design lets you run any API command the switch supports. There is no privilege tier inside ESL. Getting in is the whole game.
So the mitigation isn’t a stronger password, though obviously change it. The mitigation is that 8021 binds to 127.0.0.1, or to a VPN interface if your application layer runs on a different box. If your app server and your switch are the same machine, there is no argument for binding that socket to anything else, and the ACL in event_socket.conf.xml should say loopback.auto on top of that. Two locks on a door nobody should be able to find. Our FreeSWITCH configuration notes cover where those files live in a standard install.
I’d go further. If you’re running a multi-tenant platform and you can’t say from memory what 8021 binds to, stop reading and go check. It takes one command and it’s the highest-value thirty seconds in this article.
Verto is a parser you probably aren’t using
Ports 8081 and 8082 carry Verto, the WebSocket signalling protocol FreeSWITCH uses for browser-based calling. Four of the June advisories are in mod_verto, which is not a coincidence. It’s a WebSocket endpoint that parses attacker-controlled framing before it authenticates anything, which is a large surface by construction.
The useful question is whether you’re using it. A lot of PBX deployments have Verto listening because the module loads by default, not because anyone dialled through a browser. If nobody in your platform makes WebRTC calls, unload the module. A parser that isn’t running has no vulnerabilities, which is the only security guarantee that never expires.
If you do use WebRTC, put Verto behind a reverse proxy that terminates TLS and enforces origin checks, and don’t expose the raw port. That’s a real bit of work rather than a config toggle, and it’s worth budgeting for properly rather than doing it the week a CVE drops.
The two you’d never publish deliberately
Nobody sets out to expose MySQL on 3306 or PostgreSQL on 5432. It happens because a cloud provider’s default security group is permissive, or because someone opened it during a migration and the rule outlived the migration by two years. That database holds your tenant list, your CDRs and your credentials, so it’s the single worst thing on the box to leave reachable.
The other one is the super admin panel. In a multi-tenant platform, tenant logins and platform-operator logins are two different risk profiles wearing the same login form. If they share a hostname and a port, then every credential-stuffing run aimed at your tenants is also aimed at you. Split them: tenant panel on the public 443, admin panel on a separate host that only answers from your VPN. It costs one more DNS record. The ICTPBX architecture overview shows where that split sits relative to the rest of the stack.
How to actually check, in about five minutes
Do not audit this from inside the machine. ss -tlnp tells you what’s listening, which is a different question from what’s reachable, and the gap between those two answers is where incidents live. Firewall rules, cloud security groups and NAT all sit in between.
Run the scan from outside, against your own public IP:
nmap -Pn -sS -p 1-10000
nmap -Pn -sU -p 5060,5061
Then compare the output to the left-hand column of the first diagram. SIP, RTP and 443 are expected. Anything else that answers is a finding, and 8021 answering is an emergency.
Two caveats so you trust the result. Scan from a network that isn’t yours, because your office IP may be in an allow list you forgot about, and a cheap VPS for an hour is the honest test. And only scan infrastructure you operate, which shouldn’t need saying but does.
If you’re standing up a new box, our installation guide is the right place to bake this in, because retrofitting a bind address on a live platform means a restart and a restart means dropped registrations.
Why this beats patching faster
Patching is necessary and you should do it. But patch velocity is a race you’re running against people who read the same advisory you did and don’t have a change window. On a multi-tenant platform, a restart is a customer-visible event, so realistically you’re patching within days rather than hours.
Network exposure is the thing you control completely and in advance. Bind ESL to loopback once and the next libesl CVE, whenever it lands, is a scheduled maintenance item instead of a phone call at 2am. That asymmetry is the entire argument. You can’t predict which parser breaks next. You can decide today who gets to send it bytes.
Frequently asked questions
Can I just put the whole PBX behind a VPN?
Not the whole thing. SIP and RTP have to reach carriers and remote handsets, and a VPN in front of media introduces latency and MTU problems that show up as one-way audio. Put the management plane behind the VPN and leave the call path public but tightly rate limited. That’s the split the first diagram draws.
What if my application server is on a different machine from the switch?
Then ESL can’t bind to loopback, and you have two decent options. Put both machines on a private network segment and bind 8021 to that interface, or run a WireGuard tunnel between them and bind to the tunnel. What you should not do is open 8021 to the public internet with a source-IP firewall rule as the only control, because IP allow lists are one misapplied cloud config away from being no control at all.
Is changing the ClueCon password enough?
It’s the first thing to do and it isn’t enough. CVE-2026-49840 is in the Content-Length parsing, which happens before authentication, so a strong password doesn’t help against it. Password strength protects you from guessing. Binding to loopback protects you from the parser.
How do I know if mod_verto is even loaded?
Run fs_cli -x "module_exists mod_verto", or check whether verto.conf.xml is enabled in your modules configuration. If it’s loaded and you’re not making browser calls, unloading it removes four of the June advisories from your exposure in one step.
Does this apply to Asterisk-based systems too?
The specific CVEs don’t, since they’re FreeSWITCH modules. The principle does, exactly. Asterisk’s equivalent of ESL is AMI on port 5038, and it has the same property: getting in is the whole game, so it belongs on loopback or a VPN. Substitute the port numbers and the diagram still holds.
We’re hosted. Isn’t this our provider’s job?
Ask them which of these ports are open on your instance and see how fast you get a specific answer. A good provider will have the scan output. If the reply is general reassurance rather than a port list, run the nmap yourself, because it’s your tenant data either way.
Related reading
- What is an IP PBX if you want the ground-level explanation of what all these ports are doing
- Fraud and credit controls for the per-tenant call caps mentioned above
- ICTPBX architecture for how the management plane and call path separate in practice