Каждому техническому лидеру знакомо это неприятное чувство, когда в почту падает бюллетень о критической RCE-уязвимости (CVSS 9.2) в среде выполнения, на которой работает весь бэкенд. 21 октября 2026 года команда PHP выпустила экстренный релиз безопасности. Бэкенд encrypted1on1 написан на PHP. Наш сервис был обновлен практически сразу после выхода патча. Но этот инцидент стал наглядной практической проверкой всей нашей архитектуры: почему даже критический эксплойт сервера не привел к утечке личных заметок 1-на-1, и где пролегает честная граница того, что сквозное шифрование защищает — а что нет.

Что произошло (и почему это был повод обновиться немедленно)

21 октября 2026 года вышли версии PHP 8.5.12, 8.4.27, 8.3.36 и 8.2.35, устраняющие две опаснейшие уязвимости: CVE-2026-109618 и CVE-2026-109619. Обе получили критический рейтинг CVSS 9.2 и позволяют неавторизованному удаленному атакующему выполнять произвольный код на сервере.

Бюллетени CERT-EU и независимых исследователей безопасности подтвердили, что технические детали уже обсуждаются в открытом доступе, а в сети начали циркулировать рабочие эксплойты. На инженерном языке это означало только одно: обновление нельзя откладывать до планового технического окна в конце месяца, патчить нужно немедленно.

encrypted1on1 работает на PHP 8.5 внутри официального контейнера FrankenPHP. Обновленные образы появились на Docker Hub в тот же вечер.

Что мы предприняли

Мы обновили контейнеры на всей нашей инфраструктуре практически сразу после выхода релиза:

  • Наш сервис был пересобран на базе PHP 8.5.12 и перезапущен без простоя для пользователей.
  • Ноль правок в коде приложения: Наши production-файлы Dockerfile привязаны к тегу php8.5, поэтому стандартная пересборка контейнеров сразу подтянула исправленную версию среды выполнения.
  • Аудит и логи: Мы провели детальный анализ журналов доступа и сетевых аномалий на пограничных прокси и воркерах приложения. Никаких следов сканирования, попыток эксплуатации или подозрительной активности до и во время обновления не зафиксировано.

Почему заметки 1-на-1 в принципе нельзя прочитать с сервера

Именно в такие моменты архитектура с нулевым разглашением (Zero-Knowledge) оправдывает каждую строчку кода, потраченную на ее создание.

В классическом SaaS-сервисе для встреч или внутренней вики (Notion, Google Docs, Slack, корпоративный HRIS) выполнение произвольного кода на сервере — это катастрофа вселенского масштаба. Атакующий открывает шелл, достает пароль к базе данных и делает обычный SQL-дамп. В ту же секунду в открытом доступе оказывается вся подноготная компании: сомнения в компетенциях, споры о переработках и зарплатах, личные драмы и нефильтрованная обратная связь.

В encrypted1on1 сервер архитектурно изолирован от текста ваших разговоров. Все заметки, повестка встреч, личные мысли и черновики ответов шифруются в браузере пользователя алгоритмом AES-GCM-256 еще до того, как пакет уйдет в сеть.

Архитектура Zero-Knowledge: как сквозное шифрование локализует последствия RCE
Архитектура Zero-Knowledge: в классическом SaaS уязвимость RCE раскрывает весь архив в открытом виде. В encrypted1on1 прошлые заметки остаются математически недосягаемыми.

База данных на сервере оперирует исключительно непроницаемым шифротекстом:

  • Ответы и личные рефлексии обоих участников (как опубликованные, так и черновики);
  • Комментарии, договоренности, темы для обсуждения и задачи;
  • Личные приватные заметки каждого участника;
  • Промежуточные чекины и прогресс по целям.

Ключи шифрования генерируются на устройствах участников из их мастер-паролей с использованием ресурсоемкой функции Argon2id. Эти ключи в открытом виде никогда не отправляются на сервер — сервер хранит только запечатанные криптографические конверты, открыть которые он математически не способен.

Даже если бы злоумышленник сделал полный снимок производственной базы данных и скопировал все диски сервера, он остался бы с бессмысленным набором байт, расшифровать который без паролей конкретных пользователей невозможно. В этом и заключается суть нашей философии: мы не просим вас верить в то, что наши серверы никогда не столкнутся с уязвимостью. Ошибка в PHP, в низкоуровневой библиотеке C или в нашем коде не превращается в слив того, чем коллеги делились на встречах 1-на-1.

Честная граница: что защищает сквозное шифрование, а чего оно защитить не может

Настоящее доверие строится на предельной инженерной честности, а не на маркетинговых слоганах. Вот точные границы модели угроз при компрометации сервера:

1. Метаданные остаются видимыми для сервера. Сквозное шифрование надежно скрывает суть ваших диалогов, но сервер обязан маршрутизировать события. Атакующий с root-доступом к серверу мог бы увидеть идентификаторы аккаунтов, кто с кем проводит встречи 1-на-1, их периодичность и время проведения. Кроме того, по соображениям удобства управления процессами, мы осознанно храним незашифрованными базовые атрибуты целей (название цели, дедлайн, статус) и корпоративные шаблоны вопросов. Полная матрица открыто зафиксирована в нашей модели угроз.

2. Шифрование защищает данные в покое, но не доставку нового кода. encrypted1on1 — это веб-приложение: браузер загружает JavaScript-код с того же сервера. Если атакующий закрепляется на сервере с возможностью выполнения команд, он теоретически может модифицировать файлы фронтенда, чтобы попытаться перехватить пароль пользователя при следующем входе. Мы защищаемся от этого строгой политикой CSP (Content-Security-Policy), неизменяемыми образами контейнеров и проверкой целостности ресурсов. Однако ни одно сквозное шифрование в мире не может помешать скомпрометированному веб-серверу попытаться отдать поддельный JS будущим посетителям.

Главный вывод: Сквозное шифрование превращает то, что могло стать необратимой утечкой исторического архива данных, в обычный локализованный инцидент обновления ПО. Всё, что было написано до взлома, остается криптографически нерушимым. Сервер же необходимо оперативно патчить, чтобы защитить будущие сессии. Требуется и то, и другое.

Как обновить свой self-hosted сервер (Пошаговая инструкция)

Если вы развернули encrypted1on1 самостоятельно по нашей инструкции с Docker, обновление занимает менее двух минут и не требует миграций базы данных или правок конфигурации.

Шаг 1: Скачайте обновленный базовый образ.
Скрипт развертывания собирает образ приложения, но Docker по умолчанию может использовать уже закешированный локальный слой со старым PHP. Явный pull гарантирует скачивание свежего PHP 8.5.12:

docker pull dunglas/frankenphp:php8.5

Шаг 2: Пересоберите и перезапустите контейнеры.
Запустите штатный скрипт деплоя из каталога проекта:

PROD_COMPOSE_FILE=docker-compose.prod.yml ./docker/prod/deploy.sh

(Или просто ./docker/prod/deploy.sh, если имя compose-файла уже задано в вашем окружении).
Скрипт автоматически соберет образ с вашим текущим кодом, пересоздаст контейнер, применит миграции, обновит скомпилированный кеш и проверит статус приложения.

Совет: Делать git pull кода приложения необязательно, если вам требуется только патч безопасности. Простая пересборка текущей версии на новом базовом образе полностью закрывает уязвимость.

Шаг 3: Проверьте версию PHP в контейнере.
Убедитесь, что приложение действительно работает на обновленном рантайме:

docker compose -f docker-compose.prod.yml --env-file .env.prod exec app php -v

Команда должна вернуть PHP 8.5.12 или новее.

Если вы запускаете encrypted1on1 без Docker на собственном сервере, обновите пакеты PHP через пакетный менеджер вашей ОС (apt/dnf) и обязательно перезапустите рабочий процесс (воркер FrankenPHP или PHP-FPM). До перезапуска старый бинарник продолжает висеть в оперативной памяти.

В сухом остатке: Доверяйте математике, а не обещаниям

Уязвимости нулевого дня неизбежно будут появляться снова — в PHP, в ядре Linux, в OpenSSL или в движках браузеров. Ни один создатель ПО не может честно пообещать, что его инфраструктура никогда не окажется под угрозой.

Но что мы можем гарантировать — и что вы можете в любой момент независимо проверить в нашем открытом исходном коде — это то, что приватные разговоры вашей команды защищены законами криптографии. Когда серверы подводят, математика остается на страже.

Если у вас есть вопросы по этому релизу, криптографической модели или обновлению локальной установки, мы всегда открыты к диалогу в нашем репозитории на GitHub.