DEV Community

kozhevniko
kozhevniko

Posted on

FreeSWITCH mod_verto: a 2 MiB buffer and a 10 MiB Content-Length

FreeSWITCH mod_verto: a 2 MiB buffer and a 10 MiB Content-Length

FreeSWITCH is a software telecom stack that runs on commodity hardware, and its mod_verto module accepts HTTP POST bodies from browsers that use the Verto WebRTC client. In versions before 1.11.1 the module allocates a fixed 2 MiB buffer for a form-encoded POST body but still honours a Content-Length header of just under 10 MiB. The loop that copies the body into the buffer is bounded by the declared length rather than the buffer size, so a request that announces a large body and then delivers it can write past the end of the allocation. That is CVE-2026-49841, published with a CVSS base score of 9.8 and fixed in 1.11.1.

What the advisory says

The description is specific about the mechanism. mod_verto allocates a fixed 2 MiB buffer for a POST body with the type application/x-www-form-urlencoded, accepts Content-Length up to just under 10 MiB, and bounds the body-read loop by Content-Length. The buffer is roughly five times smaller than the largest length the handler will accept, and the copy does not consult the allocation size. The project shipped the fix in version 1.11.1 and published a GitHub security advisory.
FreeSWITCH published several fixes in the same window. CVE-2026-49472 covers a function cloned from an outdated version of libexpat, where the upstream security patch was never carried across, fixed in 1.11.0. CVE-2026-49475 and CVE-2026-45771 were published at the same time. Treat the 1.11.1 release note as the single reference for which build closes which issue.

Why the allocation and the read loop disagreed

Most heap overflows in C request handlers come from the same shape: one function decides how much memory to reserve, another function decides how much data to copy, and nothing forces the two numbers to agree. Here the two numbers are a compile-time constant of 2 MiB and a runtime header value the client chooses. Nothing in the code path compares them before the copy begins.
The reason this class of bug keeps reappearing is that the header is treated as metadata rather than as an input. Content-Length is client-controlled, and a handler that uses it as a loop bound is trusting an attacker-supplied integer. The safe pattern is to reject a request whose declared length exceeds the buffer, or to allocate from the declared length after applying an upper bound.

What an attacker gets

A heap overflow in the process that terminates SIP signalling and media is not a small problem. FreeSWITCH handles call routing, authentication for the SIP layer, and the media path, so code execution in that process reaches the control plane of the phone system. An attacker who can reach the Verto HTTP endpoint over the network does not need a credential to submit the malformed body, because the copy happens while the request is being parsed.
The practical consequence for an operator is that patching is the only reliable fix. Input filtering in front of the endpoint can reduce the attack surface, but a rule that inspects Content-Length has to be written carefully: legitimate Verto clients send large bodies, and a filter that rejects them breaks calling.

How to reduce the exposure

Upgrade to 1.11.1 or later. The advisory states the fix plainly, and the overflow is not something a configuration change can remove, because the copy happens in the handler itself.
If the upgrade has to wait, restrict who can reach the Verto endpoint. The service is normally published for browser clients, and in many deployments it is reachable from the whole internet. Placing the endpoint behind a reverse proxy that terminates TLS and enforces an allowlist for known networks removes the anonymous case, which is the one an attacker will use.
Check whether mod_verto is loaded at all. Some installations enable it for an experiment and leave it loaded after the trial ends. An unused module is an unnecessary listener.
Watch for process crashes on the FreeSWITCH host. A failed exploitation attempt and a successful one both tend to fault the process, so repeated segfaults on the media or signalling process deserve a look at the HTTP access log.

What the FreeSWITCH surface looks like from outside

A ZoomEye query on 2026-10-05 returned 4,066 assets for app="FreeSWITCH" and 401 for title="FreeSWITCH". The two numbers measure different things. The app field matches the service fingerprint that ZoomEye derives from protocol behaviour, so it finds installations that never render a product name in a web page. The title field matches the HTML title of a page, which only exists where a management interface or a default page exposes one.
Neither number is a count of vulnerable systems. The query identifies assets whose banners or page titles indicate FreeSWITCH; it does not read the installed version, and it does not test for CVE-2026-49841. The useful reading is directional: the larger app count means a meaningful number of FreeSWITCH services are reachable from the open internet, which is the precondition an attacker needs.

References

  • NVD record for CVE-2026-49841, retrieved 2026-10-05
  • FreeSWITCH security advisory GHSA-wfrq-qvg2-f88f
  • FreeSWITCH v1.11.1 release tag
  • NVD record for CVE-2026-49472, retrieved 2026-10-05

Top comments (0)