В современной торговой или сервисной компании менеджеры по продажам и операторы диспетчерских служб практически не используют настольные физические телефонные аппараты. Рабочий процесс выстроен вокруг браузерного софтфона: клик по иконке трубки прямо в интерфейсе сделки активирует голосовой поток через протокол WebRTC (Web Real-Time Communication) непосредственно в Chrome или Firefox. Через несколько секунд после завершения разговора MP3-запись диалога автоматически прикрепляется к таймлайну клиента для контроля качества и обучения персонала.
Для бизнеса в Молдове, Румынии и соседних странах Европы подобная связка стала базовым стандартом. Десятки региональных облачных SaaS-платформ предлагают готовые решения: «Воронка продаж + Сообщения из мессенджеров + Облачная АТС оператора в одном окне за 50–150 € в месяц».
Однако лишь немногие технические руководители и собственники бизнеса задумываются о том, каким именно инженерным способом браузер рядового сотрудника авторизуется на корпоративной телефонной станции (PBX).
В ходе недавнего практического аудита безопасности компании с архивом более чем в 183 800 записанных телефонных переговоров экспертная группа dlab.md выявила архитектурный дефект, позволяющий любому сотруднику перехватить контроль над корпоративным SIP-транком и выгрузить весь аудиоархив за считанные минуты.
Причиной инцидента стала не сложная уязвимость нулевого дня в стеке WebRTC, а грубое нарушение изоляции контуров: разработчики SaaS-системы отправляли главный мастер-пароль администратора АТС (sip:admin) открытым текстом прямо в браузер каждому пользователю.
Криминалистические метрики аудита корпоративной телефонии
Телеметрия авторизованного расследования уязвимостей облачной АТС
Архитектурные принципы безопасной телефонии WebRTC и SIP
Чтобы осознать масштаб рисков, необходимо рассмотреть каноническую модель построения корпоративной IP-телефонии.
При совершении звонка из веб-браузера через стек WebRTC формируются два независимых сетевых контура:
- Контур сигнализации (SIP поверх защищённых веб-сокетов - WSS) отвечает за установление вызова, передачу состояний сессии (вызов, ответ, сброс) и обмен параметрами медиа-потоков по протоколу Session Description Protocol (SDP).
- Медиа-контур (Secure Real-Time Transport Protocol - SRTP) передает зашифрованный голосовой трафик через промежуточные серверы STUN и TURN для преодоления корпоративных межсетевых экранов и механизмов трансляции адресов (NAT).
Эталонный контур безопасной WebRTC и SIP сигнализации
Аутентификация клиентской сессии
Браузер проходит авторизацию на прикладном шлюзе ERP по короткоживущему токену. Браузер никогда не получает пароли от магистральных SIP-транков.
Генерация одноразовых токенов TURN
Сервер приложений рассчитывает временный ключ HMAC-SHA1 по стандарту RFC 5389, действующий ровно 60 минут.
Шлюзование вызовов через B2BUA
Серверный узел (FreeSWITCH или Asterisk) принимает WebSocket от браузера и коммутирует вызов к оператору через изолированный транк.
Авторизованное хранение аудиозаписей
Файлы записей шифруются на диске и отдаются только через серверный контроллер, проверяющий права доступа к конкретной сделке.
Промышленная архитектура опирается на три обязательных требования:
- Выделение индивидуальных внутренних номеров с минимальными правами гарантирует, что каждый сотрудник получает персональный внутренний номер (
ext 101,ext 102) с жестким запретом на звонки за пределы разрешенных региональных кодов, либо вызовы терминируются на проксирующем узле Back-to-Back User Agent (B2BUA), полностью скрывающем реквизиты оператора связи от клиентского устройства. - Генерация эфемерных ключей медиа-релея по стандарту IETF RFC 5389 обязывает сервер передачи голоса (TURN) выпускать одноразовые криптографические связки логина и пароля на основе хэш-функции HMAC-SHA1, которые автоматически аннулируются через 3 600 секунд.
- Применение серверного контроля прав на аудиофайлы исключает публичные или последовательно пронумерованные ссылки на скачивание записей разговоров, санкционируя доступ к каждому файлу на стороне сервера с проверкой ответственного за сделку.
Посмотрим, к чему приводит пренебрежение этими правилами.
Выдача мастер-пароля sip:admin всей станции линейному персоналу (CWE-522 и CWE-250)
При открытии рабочего окна CRM клиентское приложение инициировало софтфон через фоновый запрос: GET /api/crm-own/.../softphone.
Вместо защищенного временного токена или изолированных настроек внутреннего добавочного номера API-шлюз возвращал JSON-ответ в открытом виде с полными административными учетными данными главного SIP-транка предприятия:
{
"uri": "sip:admin@company-pbx.operator.md",
"wsServers": ["wss://pbxproxy.vendor-crm.com:8443/ws"],
"authorizationUser": "admin",
"password": "Cleartext_Master_PBX_Password_2025!",
"iceServers": [
{
"urls": "turn:XX.XXX.XX.XXX:3478",
"username": "webrtc",
"credential": "static_hardcoded_password_2025"
}
]
}Практические последствия для бизнеса
- Ситуация, когда каждый стажёр становится владельцем вашей АТС, означает, что любой линейный менеджер или внешний подрядчик, нажавший клавишу
F12в браузере, получает мастер-логинadminи пароль от телефонной станции всей организации. - Прямая угроза международного телефонного фрода (SIP Toll Fraud) возникает из-за того, что при увольнении сотрудника или при компрометации его рабочего ноутбука стилером смена пароля от учётной записи CRM не аннулирует пароль от АТС. Злоумышленник, обладающий мастер-паролем и адресом открытого WebSocket-прокси, может подключить внешний генератор звонков и за несколько ночных часов сгенерировать лавину международных вызовов на премиальные платные направления, исчерпав баланс корпоративного счёта на тысячи евро.
- Открывается возможность перехвата входящих звонков руководства, поскольку права администратора на SIP-прокси позволяют зарегистрировать сторонний софтфон в качестве приоритетного обработчика входящих вызовов и перехватывать звонки ключевых клиентов компании до того, как они поступят в диспетчерскую.
Единый статический пароль TURN-сервера для всех клиентов платформы (CWE-798)
Изучение блока iceServers выявило вторую системную проблему: медиа-релей TURN использовал статическую пару учетных данных (webrtc / static_hardcoded_password_2025).
Дополнительный анализ показал, что этот же пароль был зашит в конфигурации десятков других независимых предприятий, арендующих ту же мультиарендную CRM-платформу.
Окно уязвимости: Статические пароли АТС против эфемерных токенов RFC 5389
Почему это недопустимо в мультиарендной архитектуре?
- Полная невозможность точечного отзыва доступа приводит к тому, что системный администратор, обнаруживший несанкционированный трафик со стороннего IP-адреса, не может сменить пароль на медиа-сервере без мгновенного отключения голосовой связи у всех остальных компаний-клиентов на платформе.
- Возникает паразитное использование инфраструктуры (Relay Abuse), при котором любой узел в интернете, знающий эту статическую комбинацию, может бесплатно использовать корпоративный TURN-релей в качестве публичного прокси-сервера для туннелирования любого трафика за счёт мощностей провайдера.
Сокрытие меню в интерфейсе против циклического выкачивания звонков (CWE-284)
В обследованной системе руководство было уверено, что аудиозаписи разговоров надёжно защищены: в панели управления ролями для операторов были сняты галочки видимости раздела истории звонков.
Однако программная реализация путала визуальное сокрытие с реальной защитой API:
- Снятие галочки в настройках лишь удаляло кнопку из шапки сайта.
- Серверные эндпоинты
/api/crm-own/calls/logs?page=1&limit=100и/api/crm-own/orders/boardне проверяли принадлежность записей запрашивающему пользователю. - Любой авторизованный аккаунт мог выгрузить базу данных простым циклом:
# Пакетное скачивание архива звонков компании
for page in $(seq 1 1839); do
curl -s -H "Authorization: Bearer $AGENT_TOKEN" \
"https://api.vendor-crm.com/api/crm-own/calls/logs?page=$page&limit=100" \
>> corporate_call_history.json
doneЭта команда выгрузила 1 839 страниц истории звонков, охватывающих 183 833 телефонных разговора. Каждая запись содержала прямую ссылку на облачный MP3-файл. В открытый доступ попали обсуждения персональных условий сделок, финансовые разногласия с контрагентами и претензии клиентов.
Инженерная ликвидация уязвимостей и переход на RFC 5389 HMAC-SHA1
Для надежного устранения CWE-522 и CWE-798 необходимо отказаться от статических учетных записей и внедрить алгоритм генерации эфемерных учетных данных по стандарту RFC 5389. В соответствии с этой спецификацией сервер формирует одноразовые учетные данные, вычисляемые как подпись HMAC-SHA1 по метке времени UNIX.
Ниже представлен рабочий скрипт на Python, реализующий генератор токенов стандарта RFC 5389 для взаимодействия с медиа-релеями coturn:
#!/usr/bin/env python3
"""
Генератор эфемерных учетных данных TURN по стандарту RFC 5389
Предназначен для создания короткоживущих ключей авторизации WebRTC-трафика.
"""
import hmac
import hashlib
import base64
import time
class EphemeralTurnAuthority:
def __init__(self, shared_secret: str, ttl_seconds: int = 3600):
self.shared_secret = shared_secret.encode('utf-8')
self.ttl_seconds = ttl_seconds
def generate_credentials(self, username_prefix: str) -> dict:
"""
Формирует эфемерные учетные данные, где логин содержит временную метку окончания действия.
Формат логина: <timestamp>:<username_prefix>
Формат пароля: Base64(HMAC-SHA1(secret, логин))
"""
expiry_timestamp = int(time.time()) + self.ttl_seconds
ephemeral_username = f"{expiry_timestamp}:{username_prefix}"
# Расчет подписи HMAC-SHA1 на основе общего секрета релея
digest = hmac.new(
self.shared_secret,
ephemeral_username.encode('utf-8'),
hashlib.sha1
).digest()
ephemeral_password = base64.b64encode(digest).decode('utf-8')
return {
"username": ephemeral_username,
"credential": ephemeral_password,
"ttl": self.ttl_seconds,
"expires_at": expiry_timestamp
}
if __name__ == "__main__":
# Пример вызова в боевом окружении
authority = EphemeralTurnAuthority(shared_secret="ProductionEnterpriseKey_994827419827", ttl_seconds=3600)
creds = authority.generate_credentials(username_prefix="operator_workstation_42")
print(f"Эфемерный токен:\n Username: {creds['username']}\n Password: {creds['credential']}")Защита контура телефонии в Odoo 19
В Odoo 19 интеграция телефонии выстраивается через проксирование соединений на выделенный серверный шлюз с привязкой операторов к персональным номерам. Браузер никогда не получает реквизиты внешнего магистрального транка.
Ниже приведена модель Odoo 19 на Python, обеспечивающая безопасную генерацию параметров звонка и строгий контроль доступа к аудиофайлам:
# -*- coding: utf-8 -*-
from odoo import models, fields, api, exceptions, _
import time
import hmac
import hashlib
import base64
class ResUsersSipExtension(models.Model):
_inherit = 'res.users'
sip_extension = fields.Char(string="Внутренний добавочный номер", size=10, index=True)
sip_allowed_caller_id = fields.Char(string="Закрепленная внешняя линия", readonly=True)
is_telecom_operator = fields.Boolean(string="Доступ к голосовому каналу", default=False)
def get_webrtc_session_config(self):
"""
Формирует безопасные параметры сессии WebRTC.
Мастер-пароли транков оператора связи НИКОГДА не передаются на клиент.
"""
self.ensure_one()
if not self.is_telecom_operator:
raise exceptions.AccessError(_("У пользователя нет прав на совершение голосовых вызовов."))
turn_secret = self.env['ir.config_parameter'].sudo().get_param('telecom.turn_shared_secret')
turn_realm = self.env['ir.config_parameter'].sudo().get_param('telecom.turn_realm', 'turn.dlab.md')
# Генерация эфемерного токена по стандарту RFC 5389
expiry = int(time.time()) + 3600
ephemeral_user = f"{expiry}:{self.id}"
token = hmac.new(turn_secret.encode('utf-8'), ephemeral_user.encode('utf-8'), hashlib.sha1).digest()
ephemeral_pwd = base64.b64encode(token).decode('utf-8')
return {
"ws_server": "wss://telecom-gw.dlab.md:8443/ws",
"sip_extension": self.sip_extension,
"realm": turn_realm,
"ice_servers": [
{
"urls": f"turn:{turn_realm}:3478",
"username": ephemeral_user,
"credential": ephemeral_pwd
}
]
}
class MailVoiceRecording(models.Model):
_name = 'mail.voice.recording'
_description = 'Защищенная аудиозапись телефонного разговора'
call_id = fields.Char(string="Идентификатор вызова", required=True, index=True)
lead_id = fields.Many2one('crm.lead', string="Связанная сделка CRM", required=True)
recording_file = fields.Binary(string="Аудиопоток", attachment=True)
duration_seconds = fields.Integer(string="Длительность (сек)")
def read(self, fields=None, load='_classic_read'):
"""
Контроль доступа к аудиозаписям на уровне строк (Row-Level Security).
Линейный менеджер может прослушать звонок только по назначенной ему сделке.
"""
if not self.env.user.has_group('sales_team.group_sale_manager'):
for record in self:
if record.lead_id.user_id != self.env.user:
raise exceptions.AccessError(_("Доступ запрещен: Вы не являетесь ответственным по данной сделке."))
return super().read(fields=fields, load=load)Когда допустим браузерный WebRTC, а когда необходимы физические SIP-терминалы
При проектировании корпоративной связи технический архитектор обязан взвешивать эксплуатационные свойства решений.
Матрица телеком-архитектуры: WebRTC в браузере против аппаратных IP-телефонов
Браузерный WebRTC-софтфон
Оперативная гибкость- Мгновенный старт работы без установки софта на ПК оператора
- Автоматическая привязка вызова к открытой карточке сделки
- Зависимость от загрузки CPU и стабильности песочницы браузера
- Риск заикания звука при тяжелом рендеринге интерфейса в браузере
- Требует развертывания публичных серверов STUN/TURN
Аппаратные IP-телефоны (SIP через выделенный VLAN)
Максимальная безопасность- Специализированный сигнальный процессор (DSP) без прерываний звука
- Полная изоляция в закрытом телефонном VLAN без выхода в интернет
- Учетные данные хранятся только в защищенной памяти аппарата
- Исключено влияние вредоносных расширений и зависаний операционной системы
- Непрерывная работа при сбоях рабочих станций и питание по PoE
Анализ компромиссов
- Сопоставляя скорость развертывания и периметр безопасности, важно учитывать, что WebRTC позволяет подключить 50 операторов за один час, но периметр атаки расширяется до всей операционной системы пользователя, расширений браузера и вирусов-стилеров. Физические телефоны на выделенном VLAN полностью защищены от перехвата трафика с компьютеров сотрудников.
- С точки зрения качества голосового потока, связь по WebRTC может страдать от пауз и искажений при выполнении ресурсоемких скриптов на клиентском компьютере. В ответственных диспетчерских узлах аппаратные IP-телефоны остаются эталоном надежности.
- Оценивая затраты на трафик релеев, следует помнить, что пропуск всего голосового трафика через облачные серверы TURN влечет за собой постоянные расходы на оплату исходящей полосы пропускания. В офисах со статическими IP-адресами прямое соединение через VPN-туннели исключает необходимость аренды внешних релеев.
5-минутный чеклист телеком-безопасности для CTO и CISO
Перед тем как разрешить сотрудникам звонить клиентам через браузерную CRM, проведите четыре контрольные проверки:
- Изучите ответ сервера при запуске софтфона, открыв DevTools (
F12), вызвав панель набора номера и посмотрев тело ответа эндпоинта софтфона (softphone,webrtc,sip). Если в ответе фигурирует логинadminили единый пароль вашего магистрального SIP-номера, компания находится под угрозой фрода. - Проверьте формат учетных данных TURN, изучив поле
usernameв массивеiceServers. Если в нем отсутствует метка времени UNIX через двоеточие (например,1774780800:user), в системе используются небезопасные статические пароли. - Проверьте защиту архива звонков, скопировав прямую ссылку на запись разговора в формате MP3, закрыв систему и вставив адрес в приватном окне браузера. Если запись воспроизводится без запроса авторизации, ваша база переговоров доступна всему интернету.
- Заблокируйте международные направления у оператора связи, настроив в личном кабинете провайдера запрет на вызовы по международным кодам и платным номерам, которые не требуются для регулярной деятельности компании, что ограничит финансовый ущерб в случае утечки данных.
Защита корпоративного контура связи от компрометации
Передача мастер-пароля АТС в браузер рядового менеджера предоставляет полные права администратора на телефонной станции, позволяя злоумышленнику подключить собственный софтфон, перехватывать входящие звонки клиентов, менять сценарии маршрутизации и совершать массовые вызовы на международные платные направления за счет компании (SIP Toll Fraud). Переход на стандарт RFC 5389 закрывает уязвимость медиа-релеев TURN за счет генерации временных ключей доступа на основе хэш-подписи HMAC-SHA1 с зашитой меткой истечения срока действия (обычно 3 600 секунд), благодаря чему перехваченный токен быстро теряет силу и не может использоваться для постоянных несанкционированных подключений.
На уровне сигнализации узел B2BUA (Back-to-Back User Agent, например FreeSWITCH или Asterisk) делит вызов на два раздельных диалога: браузер общается со шлюзом по защищенному WebSocket, а шлюз связывается с оператором связи по выделенному закрытому SIP-транку, что полностью исключает попадание реквизитов оператора связи на клиентские устройства. Одновременно в Odoo 19 CE и PostgreSQL файлы записей хранятся во внутреннем зашифрованном репозитории под контролем правил доступа ORM, где серверный контроллер проверяет, является ли запрашивающий пользователь ответственным менеджером по сделке или руководителем отдела, и блокирует прямые неавторизованные скачивания.
Интеграция звонков в браузер дает ощутимый прирост скорости продаж, однако удобство без надлежащей архитектурной проработки оборачивается серьезными финансовыми и репутационными потерями. Терминация вызовов на изолированном шлюзе B2BUA, внедрение эфемерных токенов RFC 5389 и разграничение доступа к архиву переговоров на базе ядра Odoo 19 и PostgreSQL надежно защищают корпоративную телефонию.
Для проведения авторизованного аудита защищенности корпоративной телефонии или организации безопасного контура связи на Odoo 19 свяжитесь с инженерной группой dlab.md.
Готовите стек ИИ и ERP к корпоративному аудиту безопасности?
Наши системные архитекторы проводят фиксированный 10-дневный Zero-Trust аудит архитектуры (OAuth 2.0 CAB, EU AI Act ст. 12/14, GDPR ст. 25, харденинг PostgreSQL и Odoo 19) с готовой дорожной картой устранения уязвимостей.