Jawaban langsung: FreeSWITCH versi 1.11.2 dan lebih lama punya celah CVE-2026-116779 dengan skor CVSS 3.1 9.8. Pesan SIP MESSAGE yang diterima profil bisa menjalankan perintah FreeSWITCH, termasuk perintah sistem operasi. Hari ini, cek versi, update ke 1.11.3, lalu cari tanda.
Celah ini sudah dipakai menyerang. CISA memasukkannya ke KEV pada 9 November 2026, dengan batas patch instansi federal AS 12 November 2026. Perbaikan sudah ada sejak 28 Agustus 2026.
Kondisi utama: Celah ini mengenai setiap profil SIP yang menerima chat masuk, dan chat aktif di setelan bawaan. ACL inbound tidak menahan jalur ini. Batas: Artikel ini tidak memuat format pesan, isi header, payload, atau urutan serangan.
Kami membaca catatan CVE-2026-116779, advisory GHSA-mg63-h38w-8p9p, catatan rilis FreeSWITCH 1.11.3, dan API catatan CVE pada 10 November 2026. Kami menguji 3 skrip cek, mitigasi sementara, dan update 1.11.2 ke 1.11.3 di container podman dengan image resmi debian:12. Container berjalan tanpa jaringan. Kami tidak mengirim pesan SIP dan tidak menguji serangan.
Masalah: pesan chat SIP yang menjalankan perintah server
FreeSWITCH adalah software telepon open source dari SignalWire. Bisnis memakainya untuk PBX kantor, call center, IVR, dan trunk SIP. FusionPBX, panel PBX yang populer di Indonesia, memakai FreeSWITCH di belakang panelnya.
Menurut catatan CVE-2026-116779, CVE-2026-116779 masuk kelas CWE-77 dan CWE-78, yaitu injeksi perintah. GitHub adalah CNA catatan ini, dan advisory berasal dari SignalWire. Skor 9.8 memakai vektor AV:N, AC:L, PR:N, dan UI:N, artinya serangan lewat jaringan, mudah, dan tanpa login.
Rilis 1.11.3 terbit 28 Agustus 2026 dan menutup celah. advisory GHSA-mg63-h38w-8p9p terbit 28 Oktober, dan catatan CVE terbit 5 November 2026. Jadi server yang belum update sejak Agustus masih terbuka.

Per 10 November 2026, celah ini masuk CISA KEV (katalog 2026.11.09). Penilaian SSVC dari CISA pada 6 November menulis Exploitation active, Automatable yes, dan Technical Impact total. Artinya serangan sudah terjadi, bisa berjalan otomatis, dan dampaknya penuh.
Cara kerja: chat proto api di jalur MESSAGE
Bagian ini memakai ringkasan resmi dan isi patch. Tujuannya membantu Anda memilih langkah, bukan menjelaskan cara menyerang.
Ringkasan dari advisory resmi
Menurut advisory, handler SIP MESSAGE di mod_sofia memakai bagian awal alamat tujuan sebagai pemilih chat proto. Modul mod_dptools mendaftarkan proto bernama api, yang menjalankan isi pesan sebagai perintah APIAPIPintu resmi yang dipakai 2 sistem untuk saling mengirim data, tanpa orang menyalin data secara manual.Buka glosarium FreeSWITCH. Jadi pihak yang pesannya diterima profil bisa menjalankan perintah dengan hak proses FreeSWITCH.
Dampak menurut advisory: perintah sistem operasi, kebocoran konfigurasi dan kredensial, dan kontrol penuh atas panggilan. Bila mod_lua dimuat, dan modul ini dimuat di setelan bawaan, Lua menjadi jalur kedua.
Setelan bawaan yang membuka jalur
- Chat aktif di setiap profil kecuali profil menulis
enable-chat=false. Conf vanilla membiarkan chat aktif di profil internal dan external. - ACL inbound tidak mencakup MESSAGE. Jadi ACL yang ketat tidak mengeluarkan profil dari risiko.
- Bila autentikasi pesan aktif, penyerang hanya butuh 1 akun di profil itu: extension, handset, atau trunk.
- Conf vanilla memuat 2 user tanpa
passworddan tanpaa1-hash: userdefaultdan contoh Skinny. User seperti ini lolos autentikasi kecualiallow-empty-passwordbernilai false.
Apa yang diubah rilis 1.11.3
Menurut advisory dan PR #3135, rilis 1.11.3 menambah parameter profil enable-chat-api-proto. Parameter ini mati kecuali Anda menulisnya, jadi proto api tertutup di setiap profil secara bawaan. Pesan ke proto itu mendapat jawaban 403, dan FreeSWITCH menulis 1 baris log dengan sumber dan perintah yang diminta.
Analisa Rama Digital: baris log 403 itu hanya muncul di server 1.11.3 atau lebih baru. Server lama tidak menulis jejak khusus untuk jalur ini. Batas: kami membaca advisory, kode patch, dan string di modul hasil build, tetapi tidak mengirim pesan uji.
Status eksploitasi per 10 November 2026
| Sumber | Status |
|---|---|
| CISA KEV | Masuk 9 November 2026, batas patch instansi federal AS 12 November 2026 |
| Catatan CVE-2026-116779 (CVSS 3.1 dari CNA) | Skor 9.8, kelas Critical, CWE-77, CWE-78, dan CWE-749 |
| CISA SSVC (6 November 2026) | Exploitation active, Automatable yes, Technical Impact total |
| Advisory SignalWire | Serangan lewat jalur ini sudah teramati di internet |
| Vendor | Celah ditutup di 1.11.3, versi terbaru per 10 November 2026 |

Skor 9.8, status KEV, dan serangan aktif membuat celah ini masuk kelas darurat. Server telepon menyimpan rekaman panggilan, voicemail, dan kredensial trunk. Penyerang juga bisa memakai trunk Anda untuk panggilan internasional, dan tagihannya jatuh ke Anda.
Siapa yang paling berisiko
Risiko bergantung pada versi, profil yang menerima chat, dan akun di direktori. Tabel ini membantu Anda mengurutkan server bila Anda mengelola banyak PBX.
| Kondisi server | Risiko | Alasan |
|---|---|---|
| Versi 1.11.2 atau lebih lama, port SIP terbuka ke internet | Tertinggi | Siapa saja di internet bisa mengirim pesan ke profil |
User default atau user lain tanpa password masih ada | Tertinggi | User itu lolos autentikasi pesan |
| FusionPBX multi-tenant atau PBX dengan banyak extension | Tinggi | Penyerang hanya butuh 1 akun dari tenant mana saja |
| Profil hanya terbuka di LAN atau VPN | Tinggi | Handset, softphone, atau laptop yang dibobol bisa mengirim pesan |
enable-chat=false di semua profil | Rendah | Jalur chat masuk tertutup, tetapi versi tetap rentan |
Sudah 1.11.3 tanpa enable-chat-api-proto | Rendah | Tetap cari tanda bila server lama terbuka sejak Agustus |

Analisa Rama Digital: banyak PBX bisnis membuka port 5060 ke internet agar softphone karyawan bisa masuk dari luar kantor. Server seperti itu masuk kelompok risiko tertinggi. Tutup port SIP untuk alamat yang tidak butuh akses, tetapi tetap update.
Server telepon sering berdiri di tepi jaringan, sama seperti VPN dan firewall. Cek juga perangkat tepi lain, misalnya celah SSLVPN SonicWall CVE-2026-19868 dan celah Ivanti Connect Secure CVE-2026-111357. Patch juga panel server, misalnya celah Control Web Panel CVE-2026-77876, dan kernel Linux di server yang sama, misalnya celah TCP kernel Linux CVE-2026-98432.
Versi rentan dan versi aman
Semua versi FreeSWITCH sampai 1.11.2 rentan terhadap CVE-2026-116779. Versi 1.11.3 menutup celah dan menjadi versi terbaru per 10 November 2026.
| Versi FreeSWITCH | Status per 10 November 2026 | Update ke |
|---|---|---|
| 1.10.x dan lebih lama | Rentan CVE-2026-116779 (9.8) | 1.11.3 hari ini |
| 1.11.0 sampai 1.11.2 | Rentan CVE-2026-116779 (9.8) | 1.11.3 hari ini |
| 1.11.3 | Aman, versi terbaru per 10 November 2026 | Pakai versi ini |

Data versi berasal dari advisory GHSA-mg63-h38w-8p9p dan catatan rilis FreeSWITCH 1.11.3. Rilis 1.11.3 tidak lagi mendukung Debian 11 Bullseye. Bila server Anda masih Debian 11, pasang langkah 4 hari ini, lalu rencanakan upgrade ke Debian 12 sebelum update FreeSWITCH.
Prasyarat sebelum mulai
- Akses SSH dengan sudo ke server FreeSWITCH, atau akses admin ke panel FusionPBX.
fs_cliyang bisa terhubung ke FreeSWITCH. Skrip memakai perintah baca saja.- Backup folder conf terbaru, misalnya
/etc/freeswitchatau/usr/local/freeswitch/conf. - Jadwal jam sepi. Restart profil dan restart FreeSWITCH memutus panggilan aktif.
- Daftar semua server FreeSWITCH dan FusionPBX, termasuk server cadangan dan server lama.
Langkah 1: Cek versi FreeSWITCH
Simpan skrip ini sebagai cek-versi-freeswitch.sh di folder ~/cek. Skrip membaca versi dari fs_cli -x version, lalu dari berkas program freeswitch bila layanan mati. Skrip lalu membandingkan versi dengan 1.11.3.
#!/usr/bin/env bash
# Cek versi FreeSWITCH terhadap CVE-2026-116779 (pesan SIP menjalankan perintah, CVSS 3.1 9.8).
# Data: catatan CVE dan advisory GHSA-mg63-h38w-8p9p dari SignalWire, rilis v1.11.3 di GitHub.
# Pakai di server: bash cek-versi-freeswitch.sh
# Pakai untuk versi yang Anda salin: bash cek-versi-freeswitch.sh 1.10.12 1.11.2 1.11.3
# Skrip hanya membaca. Skrip tidak mengubah apa pun.
# Semua versi sampai 1.11.2 rentan. Rilis 1.11.3 (28 Agustus 2026) menutup celah.
AMAN=1.11.3
lebih_kecil() { [ "$1" != "$2" ] && [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$1" ]; }
cek() {
local v="$1"
if ! [[ $v =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
printf '%-8s TIDAK DIKENAL, cocokkan manual dengan tabel versi aman\n' "$v"
return
fi
if lebih_kecil "$v" "$AMAN"; then
printf '%-8s RENTAN CVE-2026-116779 (9.8) -> update ke %s hari ini\n' "$v" "$AMAN"
else
printf '%-8s AMAN untuk CVE-2026-116779\n' "$v"
fi
}
if (( $# > 0 )); then
for v in "$@"; do cek "$v"; done
exit 0
fi
v=""
FSCLI=""
for c in "$(command -v fs_cli 2>/dev/null)" /usr/local/freeswitch/bin/fs_cli /usr/bin/fs_cli; do
[ -n "$c" ] && [ -x "$c" ] && FSCLI="$c" && break
done
FSBIN=""
for c in "$(command -v freeswitch 2>/dev/null)" /usr/local/freeswitch/bin/freeswitch /usr/bin/freeswitch; do
[ -n "$c" ] && [ -x "$c" ] && FSBIN="$c" && break
done
if [ -n "$FSCLI" ]; then
# Contoh output: FreeSWITCH Version 1.11.2-release~64bit (-release 64bit)
v=$(timeout 10 "$FSCLI" -x version 2>/dev/null | grep -oE 'Version [0-9]+\.[0-9]+\.[0-9]+' | head -n1 | cut -d' ' -f2)
[ -n "$v" ] && echo "Sumber: fs_cli (FreeSWITCH yang sedang berjalan)"
fi
if [ -z "$v" ] && [ -n "$FSBIN" ]; then
v=$(timeout 10 "$FSBIN" -version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)
[ -n "$v" ] && echo "Sumber: berkas program freeswitch (layanan mungkin tidak berjalan)"
fi
if [ -z "$v" ]; then
echo "fs_cli dan freeswitch tidak ditemukan atau tidak bisa dibaca."
echo "Coba: /usr/local/freeswitch/bin/fs_cli -x version, atau tulis versi sebagai argumen."
exit 1
fi
cek "$v"
# Di server: baca versi dari FreeSWITCH yang berjalan
bash cek-versi-freeswitch.sh
# Cek versi yang Anda catat dari server lain
bash cek-versi-freeswitch.sh 1.10.12 1.11.2 1.11.3
# Cara manual tanpa skrip
fs_cli -x version

Di FusionPBX, buka Status > SIP Status. Halaman itu menulis versi FreeSWITCH yang berjalan.
Cek hasil: "RENTAN" berarti lanjut ke langkah 2 dan 3 hari ini. "AMAN" tetap berarti jalankan langkah 5, karena server bisa sudah diserang sebelum update.
Langkah 2: Cek profil SIP dan user tanpa password
Skrip ini menjawab 3 pertanyaan: profil mana yang menerima chat masuk, user mana yang lolos tanpa password, dan langkah pengurangan risiko apa yang sudah aktif. Skrip juga membaca status profil dari sofia status.
Simpan skrip ini sebagai cek-paparan-freeswitch.sh. Skrip hanya membaca berkas conf dan menjalankan perintah baca fs_cli. Skrip tidak mengirim pesan SIP dan tidak mengubah data.
#!/usr/bin/env bash
# Cek paparan FreeSWITCH terhadap CVE-2026-116779 (pesan SIP menjalankan perintah, CVSS 3.1 9.8).
# Data: catatan CVE dan advisory GHSA-mg63-h38w-8p9p dari SignalWire, rilis v1.11.3 di GitHub.
# Pakai: bash cek-paparan-freeswitch.sh [folder-conf]
# Folder conf bawaan: /etc/freeswitch, lalu /usr/local/freeswitch/conf.
# Skrip hanya membaca berkas conf dan, bila ada, menjalankan perintah baca fs_cli (version, sofia status, global_getvar).
# Skrip tidak mengirim pesan SIP dan tidak mengubah apa pun.
# Catatan: CVE ini mengenai profil SIP yang menerima MESSAGE masuk. Profil menerima chat kecuali tertulis enable-chat=false.
AMAN=1.11.3
CONF="${1:-}"
if [ -z "$CONF" ]; then
for d in /etc/freeswitch /usr/local/freeswitch/conf; do [ -d "$d" ] && CONF="$d" && break; done
fi
if [ -z "$CONF" ] || [ ! -d "$CONF" ]; then
echo "Folder conf FreeSWITCH tidak ditemukan. Tulis foldernya sebagai argumen."
exit 1
fi
# Ganti karakter kontrol dengan tanda tanya (nama berkas dan isi conf bisa berasal dari pihak lain).
aman() { LC_ALL=C tr '\001-\037\177-\237' '[?*]'; }
# Hapus komentar XML, juga yang melewati beberapa baris.
strip() {
awk 'BEGIN{c=0} { s=$0; o=""; while (length(s)>0) {
if (c) { i=index(s,"-->"); if (i==0) { s="" } else { s=substr(s,i+3); c=0 } }
else { i=index(s,"<!--"); if (i==0) { o=o s; s="" } else { o=o substr(s,1,i-1); s=substr(s,i+4); c=1 } } } print o }' "$@"
}
lebih_kecil() { [ "$1" != "$2" ] && [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$1" ]; }
# Cari fs_cli dan versi.
FSCLI=""
for c in "$(command -v fs_cli 2>/dev/null)" /usr/local/freeswitch/bin/fs_cli /usr/bin/fs_cli; do
[ -n "$c" ] && [ -x "$c" ] && FSCLI="$c" && break
done
FSBIN=""
for c in "$(command -v freeswitch 2>/dev/null)" /usr/local/freeswitch/bin/freeswitch /usr/bin/freeswitch; do
[ -n "$c" ] && [ -x "$c" ] && FSBIN="$c" && break
done
VER=""; SUMBER=""
if [ -n "$FSCLI" ]; then
VER=$(timeout 10 "$FSCLI" -x version 2>/dev/null | grep -oE 'Version [0-9]+\.[0-9]+\.[0-9]+' | head -n1 | cut -d' ' -f2)
[ -n "$VER" ] && SUMBER="fs_cli (FreeSWITCH yang sedang berjalan)"
fi
if [ -z "$VER" ] && [ -n "$FSBIN" ]; then
VER=$(timeout 10 "$FSBIN" -version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)
[ -n "$VER" ] && SUMBER="berkas program freeswitch"
fi
RENTAN=1
echo "Folder conf: $(printf '%s' "$CONF" | aman)"
if [ -z "$VER" ]; then
echo "Versi: tidak terbaca. Skrip menganggap versi rentan."
elif lebih_kecil "$VER" "$AMAN"; then
echo "Versi: $VER (RENTAN, perbaikan ada di $AMAN). Sumber: $SUMBER"
else
RENTAN=0
echo "Versi: $VER (sudah memuat perbaikan). Sumber: $SUMBER"
fi
echo
true_val() { # niat sama dengan switch_true di FreeSWITCH
local v; v=$(printf '%s' "$1" | tr 'A-Z' 'a-z')
case "$v" in true|yes|on|enabled|active|allow) return 0 ;; esac
[[ $v =~ ^[0-9]+$ ]] && [ "$v" -gt 0 ] && return 0
return 1
}
echo "1. Profil SIP dan jalur chat"
PROF_FILES=()
while IFS= read -r -d '' f; do PROF_FILES+=("$f"); done < <(find "$CONF/sip_profiles" "$CONF/autoload_configs/sofia.conf.xml" -type f -name '*.xml' -print0 2>/dev/null)
n_prof=0; n_chat=0; n_api=0; n_noauth=0; nama_chat=""
for f in "${PROF_FILES[@]}"; do
while IFS='|' read -r nama chat api am dam; do
[ -z "$nama" ] && continue
n_prof=$((n_prof + 1))
if [ "$chat" = "#kosong#" ]; then chat_s="AKTIF (bawaan)"; chat_on=1
elif true_val "$chat"; then chat_s="AKTIF"; chat_on=1
else chat_s="mati"; chat_on=0; fi
if [ "$api" = "#kosong#" ]; then api_on=0; elif true_val "$api"; then api_on=1; else api_on=0; fi
if [ "$dam" != "#kosong#" ]; then
true_val "$dam" && auth_on=0 || auth_on=1
elif [ "$am" != "#kosong#" ] && ! true_val "$am"; then auth_on=0
else auth_on=1; fi
if (( RENTAN == 0 )); then api_s="$( ((api_on)) && echo AKTIF || echo mati )"; else api_s="tidak dikenal di versi ini"; fi
((auth_on)) && auth_s="aktif" || auth_s="MATI"
printf ' %-14s enable-chat: %-14s enable-chat-api-proto: %-26s auth-pesan: %s\n' "$(printf '%s' "$nama" | aman)" "$chat_s" "$api_s" "$auth_s"
if (( chat_on )); then
n_chat=$((n_chat + 1)); nama_chat+="$nama "
(( RENTAN == 0 && api_on )) && n_api=$((n_api + 1))
(( auth_on == 0 )) && n_noauth=$((n_noauth + 1))
fi
done < <(strip "$f" | tr '\n' ' ' | awk -v RS='<' '
function attr(s, k, t) { if (match(s, k "=\"[^\"]*\"")) { t = substr(s, RSTART + length(k) + 2, RLENGTH - length(k) - 3); return t } return "" }
/^profile[ \t]/ { in_p = 1; nm = attr($0, "name"); chat = api = am = dam = "#kosong#"; next }
/^\/profile/ { if (in_p) print nm "|" chat "|" api "|" am "|" dam; in_p = 0; next }
in_p && /^param[ \t]/ { k = attr($0, "name"); v = attr($0, "value")
if (k == "enable-chat") chat = v; else if (k == "enable-chat-api-proto") api = v
else if (k == "auth-messages") am = v; else if (k == "disable-auth-messages") dam = v }')
done
(( n_prof == 0 )) && echo " Tidak ada profil di $(printf '%s' "$CONF" | aman)/sip_profiles. Cek folder conf."
echo " Profil dengan chat aktif: $n_chat dari $n_prof"
if [ -n "$FSCLI" ]; then
st=$(timeout 10 "$FSCLI" -x 'sofia status' 2>/dev/null | awk -F'\t' '{ for (i=1;i<=NF;i++) gsub(/^ +| +$/,"",$i) } $2=="profile" { printf " berjalan: %-14s %s\n", $1, $3 }')
if [ -n "$st" ]; then printf '%s\n' "$st" | LC_ALL=C tr '\001-\011\013-\037\177-\237' '[?*]'; else echo " fs_cli tidak bisa membaca sofia status (layanan mati atau sandi fs_cli berbeda)."; fi
fi
echo "2. User direktori tanpa password dan tanpa a1-hash"
n_user=0; daftar=""
while IFS= read -r -d '' f; do
while IFS='|' read -r uid ada; do
[ -z "$uid" ] && continue
[ "$ada" = "kosong" ] || continue
n_user=$((n_user + 1))
(( n_user <= 10 )) && daftar+=" - user $(printf '%s' "$uid" | aman) di $(printf '%s' "${f#$CONF/}" | aman)"$'\n'
done < <(strip "$f" | tr '\n' ' ' | awk -v RS='<' '
function attr(s, k, t) { if (match(s, k "=\"[^\"]*\"")) { t = substr(s, RSTART + length(k) + 2, RLENGTH - length(k) - 3); return t } return "" }
/^user[ \t]/ { in_u = 1; id = attr($0, "id"); has = 0; if (attr($0, "type") == "pointer") has = 1; next }
/^\/user/ { if (in_u) print id "|" (has ? "ada" : "kosong"); in_u = 0; next }
in_u && /^param[ \t]/ { k = attr($0, "name"); v = attr($0, "value"); if ((k == "password" || k == "a1-hash") && v != "") has = 1 }')
done < <(find "$CONF/directory" -type f -name '*.xml' -print0 2>/dev/null)
if (( n_user > 0 )); then
echo " $n_user user bisa masuk tanpa password (kecuali allow-empty-password bernilai false):"
printf '%s' "$daftar"
else
echo " 0 user."
fi
sandi_bawaan=$(strip "$CONF/vars.xml" 2>/dev/null | grep -oE 'default_password=[^"]*' | head -n1 | cut -d= -f2)
if [ "$sandi_bawaan" = "1234" ]; then
n_def=$(grep -rhE 'name="password" value="\$\$\{default_password\}"' "$CONF/directory" 2>/dev/null | wc -l)
echo " Sandi bawaan 1234 masih aktif di vars.xml dan dipakai $n_def user. Ganti sandi itu."
fi
echo "3. Pengurangan risiko lain"
sysoff=""
if [ -n "$FSCLI" ]; then
sysoff=$(timeout 10 "$FSCLI" -x 'global_getvar disable_system_api_commands' 2>/dev/null | head -n1)
fi
if [ -n "$sysoff" ] && true_val "$sysoff"; then
echo " disable_system_api_commands: true (perintah system mati). API lain tetap terjangkau."
elif strip "$CONF/vars.xml" 2>/dev/null | grep -qE 'disable_system_api_commands=true'; then
echo " disable_system_api_commands=true ada di vars.xml (berlaku setelah FreeSWITCH dijalankan ulang)."
else
echo " disable_system_api_commands: tidak diatur. Perintah system masih tersedia."
fi
if strip "$CONF/autoload_configs/modules.conf.xml" 2>/dev/null | grep -qE '<load[[:space:]]+module="mod_lua"'; then
echo " mod_lua: ada di daftar muat modules.conf.xml (jalur kedua lewat Lua). Hapus baris itu bila tidak dipakai."
else
echo " mod_lua: tidak ada di daftar muat modules.conf.xml."
fi
echo
if (( RENTAN )); then
if (( n_chat > 0 )); then
echo "Hasil: PAPARAN TINGGI. Versi rentan dan $n_chat profil menerima MESSAGE masuk (${nama_chat% })."
echo "Update ke $AMAN. Sampai update: tulis enable-chat=false di profil tanpa chat SIP masuk."
else
echo "Hasil: PAPARAN RENDAH. Versi rentan, tetapi tidak ada profil yang menerima chat. Tetap update ke $AMAN."
fi
else
if (( n_api > 0 )); then
echo "Hasil: PAPARAN TINGGI. Versi sudah diperbaiki, tetapi $n_api profil menulis enable-chat-api-proto aktif."
echo "Hapus parameter itu kecuali peer tepercaya memang butuh."
else
echo "Hasil: AMAN. Versi memuat perbaikan dan tidak ada profil yang membuka proto api."
fi
fi
# Folder conf bawaan: /etc/freeswitch, lalu /usr/local/freeswitch/conf
bash cek-paparan-freeswitch.sh
# Folder conf lain, misalnya hasil instalasi khusus
bash cek-paparan-freeswitch.sh /opt/freeswitch/conf
# Cek dari server: port SIP yang terbuka (5060 dan 5080 di setelan bawaan)
sudo ss -lunp | grep -E ':(5060|5080)\b'

Di uji kami dengan conf vanilla, 4 dari 4 profil menerima chat masuk, dan 2 user lolos tanpa password: default dan contoh Skinny. Hasilnya PAPARAN TINGGI. Skrip juga menemukan sandi bawaan 1234 di vars.xml, yang dipakai 21 user contoh.
Conf vanilla juga menulis mod_lua di daftar muat. Menurut advisory, Lua menjadi jalur kedua. Build uji kami tidak memasang mod_lua, jadi skrip hanya membaca daftar muat itu.
Di FusionPBX, skrip tetap membaca berkas XML profil yang dibuat panel. Tetapi ubah setelan lewat panel, karena panel menulis ulang berkas itu.
Cek hasil: "PAPARAN TINGGI" berarti update dalam 1 jam, atau pakai langkah 4 sekarang. Hapus atau beri password pada setiap user tanpa password, karena user itu juga membuka jalur lain.
Langkah 3: Backup, lalu update ke 1.11.3
Hanya update yang menutup celah. Buat backup conf lebih dulu, lalu update dengan cara yang sama seperti instalasi awal Anda.
# Instalasi dari source. Jalankan di jam sepi, karena restart memutus panggilan aktif.
# 1. Backup folder conf, lalu catat opsi configure dari build lama
sudo tar czf /root/conf-freeswitch-sebelum-update.tar.gz -C /usr/local/freeswitch conf
grep -m1 '\$ ./configure' /usr/src/freeswitch-1.11.2/config.log
# 2. Unduh source 1.11.3, lalu build dengan modules.conf dan opsi configure yang sama
cd /usr/src
sudo curl -fL -o freeswitch-1.11.3.tar.gz https://github.com/signalwire/freeswitch/archive/refs/tags/v1.11.3.tar.gz
sudo tar xzf freeswitch-1.11.3.tar.gz && cd freeswitch-1.11.3
sudo cp ../freeswitch-1.11.2/modules.conf .
sudo ./bootstrap.sh -j && sudo ./configure --disable-libvpx --disable-libyuv && sudo make -j4
# 3. Hentikan FreeSWITCH, pasang, lalu jalankan lagi
fs_cli -x 'shutdown'
sudo make install
sudo systemctl start freeswitch
# 4. Cek versi lagi
bash ~/cek/cek-versi-freeswitch.sh

- Buat backup folder conf, lalu pindahkan berkasnya keluar dari server.
- Catat opsi configure dari baris pertama
config.logdi folder source lama. Pakai opsi yang sama di build baru. - Build 1.11.3, hentikan FreeSWITCH di jam sepi, jalankan
make install, lalu jalankan FreeSWITCH lagi. - Jalankan lagi
cek-versi-freeswitch.sh. Hasil yang benar: "AMAN untuk CVE-2026-116779". - Buat 1 panggilan uji masuk dan 1 panggilan uji keluar, lalu ulangi di setiap server.
Di uji kami, build 1.11.3 dari source berhasil dengan modules.conf yang sama. Sesudah make install, conf lama tetap dipakai, 4 profil berjalan lagi, dan fs_cli menulis versi 1.11.3. String log penolakan proto api ada di mod_sofia.so hasil build.
Untuk instalasi dari paket Debian SignalWire, pastikan versi kandidat sudah 1.11.3, lalu update paket FreeSWITCH. Repositori itu butuh token akses SignalWire, jadi kami tidak menguji jalur ini.
# Instalasi dari paket Debian SignalWire (tidak kami uji): cek versi kandidat lebih dulu
sudo apt-get update
apt-cache policy freeswitch | head -n 3
# Update hanya paket FreeSWITCH yang sudah terpasang
sudo apt-get install --only-upgrade $(dpkg-query -W -f='${binary:Package}\n' 'freeswitch*')
sudo systemctl restart freeswitch
Untuk FusionPBX, cek cara instalasi FreeSWITCH di server Anda: dari source atau dari paket. Lalu pakai jalur yang sama. Jangan menulis enable-chat-api-proto=true sesudah update, kecuali peer tepercaya memang butuh proto itu.

Cek hasil: skrip versi menulis "AMAN" di setiap server, skrip paparan menulis "AMAN", dan panggilan uji masuk dan keluar berhasil.
Langkah 4: Matikan chat SIP masuk bila update tertunda
Langkah ini hanya lapisan sementara. Pakai langkah ini bila Anda belum bisa update hari ini, misalnya karena server masih Debian 11 atau butuh uji di server cadangan dulu.
Menurut advisory, enable-chat=false menghentikan pesan sebelum pemilih proto dibaca. Efek sampingnya, semua chat SIP masuk di profil itu mati. Panggilan memakai jalur lain, jadi menurut analisa kami panggilan tidak terpengaruh.
# Bila update belum bisa hari ini: matikan chat SIP masuk di setiap profil.
# Ganti /usr/local/freeswitch/conf dengan folder conf Anda, misalnya /etc/freeswitch.
cd /usr/local/freeswitch/conf/sip_profiles
for f in *.xml; do sudo cp -p "$f" "$f.bak-cve"; done
sudo sed -i 's|<settings>|<settings>\n <param name="enable-chat" value="false"/>|' *.xml
grep -n 'enable-chat' *.xml
# Muat ulang conf, lalu restart setiap profil. Restart profil memutus panggilan di profil itu.
fs_cli -x 'reloadxml'
for p in $(fs_cli -x 'sofia status' | awk '$2=="profile" {print $1}'); do fs_cli -x "sofia profile $p restart"; done
fs_cli -x 'sofia status' | grep -c RUNNING
bash ~/cek/cek-paparan-freeswitch.sh

Di uji kami, 4 profil menerima enable-chat=false, lalu ke-4 profil berjalan lagi sesudah restart. Skrip paparan berubah dari PAPARAN TINGGI ke PAPARAN RENDAH, tetapi versi tetap 1.11.2.
Di FusionPBX, buka Advanced > SIP Profiles, buka setiap profil, lalu tambah setelan enable-chat bernilai false. Simpan, lalu restart profil dari Status > SIP Status. Kami tidak menguji FusionPBX.
2 langkah lain dari advisory tidak menutup jalur ini. auth-messages dan penghapusan user tanpa password hanya membatasi pengirim ke akun terdaftar. disable_system_api_commands=true hanya mematikan perintah system, sementara perintah API lain tetap terjangkau.
Analisa Rama Digital: enable-chat=false hanya mengurangi jalan masuk. Celah tetap ada di kode sampai versi 1.11.3. Sesudah update, Anda boleh mengembalikan chat bila tim memakainya.
Cek hasil: grep menemukan enable-chat bernilai false di setiap profil, semua profil berstatus RUNNING, dan skrip paparan menulis PAPARAN RENDAH.
Langkah 5: Cari tanda pemakaian
Rilis rentan terakhir terbit 9 Agustus 2026, dan serangan sudah teramati. Cari tanda di setiap server, termasuk server yang sudah update hari ini.
Simpan skrip ini sebagai cek-tanda-freeswitch.sh. Skrip membaca 5 hal: baris log 403 penolakan proto api, proses anak FreeSWITCH, berkas conf yang berubah, user direktori di berkas yang baru berubah, dan crontab serta authorized_keys milik user layanan.
Jalankan dengan sudo, karena log dan crontab user layanan biasanya hanya terbaca root. Skrip tidak menjalankan perintah FreeSWITCH. Skrip mengganti karakter kontrol di nama berkas dan baris log dengan tanda tanya, agar teks dari penyerang tidak mengubah terminal Anda.
#!/usr/bin/env bash
# Cari tanda pemakaian CVE-2026-116779 (FreeSWITCH) di log, proses, folder conf, dan akun layanan.
# Pakai: sudo bash cek-tanda-freeswitch.sh [folder-log] [folder-conf] [hari] [user-layanan]
# Bawaan: log /var/log/freeswitch lalu /usr/local/freeswitch/log. Conf /etc/freeswitch lalu /usr/local/freeswitch/conf.
# Hari bawaan 30. User layanan bawaan: pemilik proses freeswitch dan user "freeswitch" bila ada.
# Skrip hanya membaca berkas dan daftar proses. Skrip tidak menjalankan perintah FreeSWITCH.
# Server yang masih di bawah 1.11.3 tidak menulis log penolakan. Hasil kosong di sana bukan bukti aman.
# Nama berkas dan baris log bisa berasal dari penyerang, jadi skrip mengganti karakter kontrol dengan tanda tanya.
LOGDIR="${1:-}"; CONF="${2:-}"; HARI="${3:-30}"; USERS_ARG="${4:-}"
if [ -z "$LOGDIR" ]; then for d in /var/log/freeswitch /usr/local/freeswitch/log; do [ -d "$d" ] && LOGDIR="$d" && break; done; fi
if [ -z "$CONF" ]; then for d in /etc/freeswitch /usr/local/freeswitch/conf; do [ -d "$d" ] && CONF="$d" && break; done; fi
[[ $HARI =~ ^[0-9]+$ ]] || HARI=30
aman() { LC_ALL=C tr '\001-\037\177-\237' '[?*]'; }
strip() {
awk 'BEGIN{c=0} { s=$0; o=""; while (length(s)>0) {
if (c) { i=index(s,"-->"); if (i==0) { s="" } else { s=substr(s,i+3); c=0 } }
else { i=index(s,"<!--"); if (i==0) { o=o s; s="" } else { o=o substr(s,1,i-1); s=substr(s,i+4); c=1 } } } print o }' "$@"
}
tanda=0
echo "1. Log: MESSAGE ke proto api yang ditolak 403 (hanya server 1.11.3 atau lebih baru)"
LOGS=()
if [ -n "$LOGDIR" ] && [ -d "$LOGDIR" ]; then
for f in "$LOGDIR"/freeswitch.log*; do [ -f "$f" ] && LOGS+=("$f"); done
fi
if (( ${#LOGS[@]} == 0 )); then
echo " Log tidak ditemukan. Tulis folder log sebagai argumen pertama."
else
isi=$(zcat -f "${LOGS[@]}" 2>/dev/null | LC_ALL=C tr '\001-\011\013-\037\177-\237' '[?*]' | grep -F "rejected a MESSAGE from" | grep -F "'api' chat proto")
n=$(printf '%s' "$isi" | grep -c .)
echo " Baris penolakan: $n"
if (( n > 0 )); then
printf '%s\n' "$isi" | sed -E "s/^([0-9-]+ [0-9:]+)[^[]*\[[A-Z]+\].*Profile \[([^]]*)\] rejected a MESSAGE from ([^ ]*) \(([^)]*)\) addressed.*/ \1 profil \2 dari \3 (\4)/" | cut -c1-150 | tail -n 10
echo " 5 sumber teratas:"
printf '%s\n' "$isi" | sed -E 's/.*rejected a MESSAGE from [^ ]* \(([^):]*)[:)].*/\1/' | sort | uniq -c | sort -rn | head -n 5 | awk '{printf " IP %s: %d kali\n", $2, $1}'
echo " Perintah yang diminta ada di berkas log. Baca di sana, jangan salin ke terminal."
tanda=$((tanda + 1))
fi
fi
echo "2. Proses anak dari proses freeswitch"
PID=$(pgrep -x freeswitch 2>/dev/null | head -n1)
if [ -z "$PID" ]; then
echo " Proses freeswitch tidak berjalan."
else
anak=$(ps -eo pid=,ppid=,etime=,args= 2>/dev/null | awk -v root="$PID" '
{ pid=$1; ppid=$2; et=$3; $1=$2=$3=""; sub(/^ +/,""); par[pid]=ppid; cmd[pid]=$0; ela[pid]=et }
END { for (p in par) { q=p; while (q in par) { if (par[q]==root) { printf "%s %s %s\n", p, ela[p], substr(cmd[p],1,100); break } q=par[q] } } }' | aman)
if [ -n "$anak" ]; then
echo " PERIKSA: FreeSWITCH biasanya tidak punya proses anak yang hidup lama:"
printf '%s\n' "$anak" | sed 's/^/ PID /'
tanda=$((tanda + 1))
else
echo " 0 proses anak."
fi
fi
echo "3. Berkas conf yang berubah dalam $HARI hari terakhir"
if [ -z "$CONF" ] || [ ! -d "$CONF" ]; then
echo " Folder conf tidak ditemukan. Tulis folder conf sebagai argumen kedua."
else
baru=$(find "$CONF" -type f -mtime -"$HARI" -printf '%TY-%Tm-%Td %TH:%TM %s B %p\0' 2>/dev/null | aman | tr '\0' '\n' | sort | tail -n 15)
if [ -n "$baru" ]; then
echo " PERIKSA: cocokkan dengan perubahan yang tim Anda buat:"
printf '%s\n' "$baru" | sed 's/^/ /'
tanda=$((tanda + 1))
else
echo " 0 berkas."
fi
fi
echo "4. User direktori di berkas yang baru berubah"
if [ -n "$CONF" ] && [ -d "$CONF/directory" ]; then
n_u=0; dft=""
while IFS= read -r -d '' f; do
ids=$(strip "$f" | tr '\n' ' ' | awk -v RS='<' '/^user[ \t]/ { if (match($0, "id=\"[^\"]*\"")) print substr($0, RSTART+4, RLENGTH-5) }' | aman | tr '\n' ' ')
[ -z "$ids" ] && continue
n_u=$((n_u + 1)); dft+=" $(stat -c '%y' "$f" | cut -c1-16) user: ${ids% } ($(printf '%s' "${f#$CONF/}" | aman))"$'\n'
done < <(find "$CONF/directory" -type f -name '*.xml' -mtime -"$HARI" -print0 2>/dev/null)
if (( n_u > 0 )); then
echo " PERIKSA: user yang tidak Anda kenal bisa menjadi akun untuk jalur ini:"
printf '%s' "$dft"
tanda=$((tanda + 1))
else
echo " 0 berkas direktori baru."
fi
else
echo " Folder directory tidak ada."
fi
echo "5. Crontab dan authorized_keys milik user layanan"
USERS=()
if [ -n "$USERS_ARG" ]; then USERS=("$USERS_ARG"); else
[ -n "$PID" ] && USERS+=("$(ps -o user= -p "$PID" 2>/dev/null | tr -d ' ')")
getent passwd freeswitch >/dev/null 2>&1 && USERS+=(freeswitch)
fi
USERS=($(printf '%s\n' "${USERS[@]}" | sort -u))
if (( ${#USERS[@]} == 0 )); then
echo " User layanan tidak ditemukan. Tulis nama user sebagai argumen keempat."
fi
for u in "${USERS[@]}"; do
[[ $u =~ ^[a-z_][a-z0-9_.-]*$ ]] || continue
ada=0
for cf in "/var/spool/cron/crontabs/$u" "/var/spool/cron/$u"; do
if [ -f "$cf" ]; then
ada=1
aktif=$(grep -cvE '^[[:space:]]*(#|$)' "$cf")
echo " PERIKSA: crontab user $u ada ($(stat -c '%y' "$cf" | cut -c1-16), $aktif baris aktif)."
grep -vE '^[[:space:]]*(#|$)' "$cf" | head -n 5 | cut -c1-100 | aman | sed 's/^/ /'
tanda=$((tanda + 1))
fi
done
home=$(getent passwd "$u" 2>/dev/null | cut -d: -f6)
if [ -n "$home" ] && [ -f "$home/.ssh/authorized_keys" ]; then
ada=1
n_k=$(grep -cvE '^[[:space:]]*(#|$)' "$home/.ssh/authorized_keys")
echo " PERIKSA: authorized_keys user $u ada ($n_k kunci, diubah $(stat -c '%y' "$home/.ssh/authorized_keys" | cut -c1-16))."
tanda=$((tanda + 1))
fi
(( ada == 0 )) && echo " User $u: tidak ada crontab dan tidak ada authorized_keys."
done
echo
if (( tanda > 0 )); then
echo "Hasil: $tanda TANDA perlu diperiksa. Bila berkas atau baris bukan milik tim Anda, lanjut ke respons insiden."
else
echo "Hasil: tidak ada TANDA dari cek ini. Log bisa dihapus penyerang, jadi tetap update dan pantau."
fi
# Log, proses anak, conf yang berubah dalam 30 hari, user direktori baru, crontab, dan authorized_keys
sudo bash cek-tanda-freeswitch.sh
# Folder log dan conf lain, rentang 75 hari (sejak rilis 1.11.2 pada 9 Agustus 2026)
sudo bash cek-tanda-freeswitch.sh /var/log/freeswitch /etc/freeswitch 75
# Cek panggilan keluar yang asing di CDR CSV (bila mod_cdr_csv aktif)
sudo tail -n 50 /var/log/freeswitch/cdr-csv/Master.csv


Di uji kami, server tidak pernah diserang. Skrip tetap menemukan berkas profil yang berubah, yaitu perubahan kami sendiri di langkah 4. Cocokkan setiap berkas yang muncul dengan catatan perubahan tim Anda.
Baris log 403 hanya ada sesudah update ke 1.11.3. Di server lama, cari jejak lain: proses sh atau bash di bawah proses freeswitch, user baru di direktori, dan panggilan internasional asing di CDR.
Cek hasil: skrip menulis "tidak ada TANDA dari cek ini", atau setiap tanda cocok dengan perubahan tim Anda. Log bisa dihapus penyerang, jadi tidak ada tanda belum berarti aman.
Bila ada 1 tanda saja, simpan log, berkas conf, dan daftar proses sebagai bukti. Ganti password semua extension, password trunk SIP, dan password fs_cli di event_socket.conf.xml. Lalu update ke 1.11.3 dan minta penyedia trunk memeriksa tagihan.
Server telepon menyimpan rekaman panggilan, voicemail, dan nomor pelanggan. Bila data pribadi bocor, UU 27/2022 tentang Pelindungan Data Pribadi mewajibkan pemberitahuan tertulis paling lambat 3 kali 24 jam sesudah kebocoran. Baca juga panduan security, privacy, dan UU PDP untuk perusahaan.
Contoh: 1 pagi respons untuk 3 server telepon
Simulasi ini memakai data dummy. Nama server, waktu, dan hasil bukan data pelanggan.
| Waktu (WIB) | Server dummy | Yang dicek | Hasil | Tindakan |
|---|---|---|---|---|
| 08.00 | callcenter-a (FusionPBX, FreeSWITCH 1.10.12, port 5060 terbuka ke internet) | Langkah 1, 2, dan 5 | PAPARAN TINGGI, 1 proses sh asing di bawah freeswitch | Respons insiden, lalu update |
| 08.30 | pbx-kantor-b (1.11.2 dari source, hanya LAN) | Langkah 1 dan 2 | PAPARAN TINGGI, user default tanpa password | Langkah 4 pagi ini, update ke 1.11.3 jam 12.00 |
| 09.00 | trunk-c (1.11.3, Debian 12) | Langkah 1, 2, dan 5 | AMAN, 0 TANDA | Simpan output sebagai bukti |
Pelajaran dari simulasi: server yang terbuka ke internet butuh langkah 5 dulu, bukan hanya update. Update menutup celah, tetapi tidak menghapus akun, kunci SSH, atau crontab yang sudah ditanam.
Siapa yang memasang patch
Tanggung jawab patch berbeda per jenis layanan, jadi tabel ini membantu Anda tahu siapa yang bergerak hari ini.
| Jenis layanan | Pemegang patch | Yang Anda kerjakan |
|---|---|---|
| FreeSWITCH atau FusionPBX di VPS sendiri | Tim Anda | Langkah 1 sampai 5 |
| FusionPBX yang dikelola vendor atau integrator | Sesuai kontrak perawatan | Tanya versi FreeSWITCH hari ini, lalu minta bukti output langkah 1 dan 5 |
| Cloud PBX dari penyedia | Penyedia | Tanya apakah layanan memakai FreeSWITCH dan kapan patch terpasang |
| Perangkat PBX on-premise berbasis FreeSWITCH | Vendor perangkat | Cek firmware baru, lalu tutup port SIP dari internet sampai firmware terpasang |
Rekomendasi Rama Digital: masukkan FreeSWITCH ke jadwal patch bulanan, sama seperti sistem operasi. Patch celah kritis dalam 24 jam, dan celah yang masuk CISA KEV pada hari yang sama.
Checklist hari ini
- Buat daftar semua server FreeSWITCH dan FusionPBX. Pemilik: tim IT. Bukti: daftar server dan versi.
- Cek versi dengan langkah 1. Pemilik: admin PBX. Bukti: output skrip.
- Cek profil dan user tanpa password dengan langkah 2. Pemilik: admin PBX. Bukti: output skrip.
- Buat backup conf, lalu update ke 1.11.3. Pemilik: admin PBX. Bukti: output skrip versi sesudah update.
- Bila update tertunda, pasang langkah 4. Pemilik: admin PBX. Bukti: output skrip paparan.
- Cari tanda dengan langkah 5. Pemilik: admin PBX dan tim keamanan. Bukti: output skrip dan CDR 30 hari.
- Tutup port SIP dari internet untuk alamat yang tidak butuh akses.
Tanya jawab
Apakah celah ini sudah dipakai menyerang?
Ya. Catatan CVE dan advisory SignalWire menulis bahwa serangan lewat jalur ini sudah teramati. CISA memasukkan celah ini ke KEV pada 9 November 2026.
Server saya hanya terbuka di LAN. Apakah saya aman?
Tidak. Setiap akun atau perangkat yang bisa mengirim pesan ke profil bisa memakai jalur ini. ACL inbound juga tidak mencakup MESSAGE, jadi tetap update ke 1.11.3.
Apakah disable_system_api_commands menutup celah ini?
Tidak. Setelan itu hanya mematikan perintah system. Menurut advisory, perintah API lain tetap terjangkau, termasuk memuat modul dan membuat panggilan.
Saya memakai FusionPBX. Apakah saya terdampak?
Ya, bila FreeSWITCH di bawah panel masih 1.11.2 atau lebih lama. Cek versi di Status > SIP Status, lalu update FreeSWITCH dengan jalur instalasi server Anda.
Apakah enable-chat=false memutus panggilan?
Tidak untuk panggilan baru. Setelan itu hanya mematikan chat SIP masuk. Tetapi restart profil untuk memakai setelan itu memutus panggilan aktif di profil tersebut.
Bagaimana saya tahu ada yang menyalahgunakan celah ini?
Jalankan langkah 5. Cek proses anak freeswitch, conf dan user yang berubah, crontab, kunci SSH, dan panggilan asing di CDR. Sesudah update, cek juga baris log 403 penolakan proto api.
Langkah berikutnya
Batas yang tetap berlaku: enable-chat=false bukan perbaikan, dan update tidak menghapus akun atau kunci yang sudah ditanam. Bila server Anda menunjukkan tanda di langkah 5, atau Anda butuh bantuan audit dan pemulihan, pakai Vibe Code Rescue. Untuk 1 masalah mendesak hari ini, jadwalkan sesi 30 menit.
Sumber
- catatan CVE-2026-116779: ringkasan resmi, CWE-77, CWE-78, CWE-749, rentang versi rentan, dan skor CVSS 3.1 9.8.
- advisory GHSA-mg63-h38w-8p9p: konfigurasi yang terkena, user tanpa password di conf vanilla, langkah sementara, status serangan, dan penemu.
- catatan rilis FreeSWITCH 1.11.3: tanggal rilis 1.11.3, perbaikan keamanan, dan Debian 11 yang tidak didukung lagi.
- PR #3135: parameter
enable-chat-api-protodan log penolakan 403. - API catatan CVE: data mentah catatan CVE dan penilaian SSVC dari CISA.
- CISA KEV: status CISA KEV per 10 November 2026.
- UU 27/2022 tentang Pelindungan Data Pribadi: kewajiban melapor kebocoran data pribadi.

