Инцидент eMudhra: Go закрыл дыру за 7,5 часа — что делать в 2026

· ·

Инцидент eMudhra: Go закрыл дыру за 7,5 часа — что делать в 2026

PrimeCoder · 2026 · формат: news

Что произошло, почему это важно и что взять в работу.

Security-релизы рантайма теперь выходят за часы, и это обязывает пересобрать все Go-бинарники, а не просто обновить систему.

Связанные услуги: каталог, AI Boost Team, стать клиентом.

Семь с половиной часов, или новая скорость патчей

17 октября 2026 года Mozilla занесла в OneCRL восемь промежуточных сертификатов eMudhra. 19 октября вышли Go 1.27.3 и 1.26.10. Между первым сообщением о проблеме и опубликованным релизом прошло меньше семи с половиной часов.

Для владельца бизнеса это выглядит как новость из чужой жизни: какие-то сертификаты, какой-то удостоверяющий центр в Индии, язык Go где-то на бэкенде. Только вот Go сегодня держит платёжные шлюзы, интеграции с банками, сервисы доставки, внутренние API у огромного числа российских компаний. И весь этот парк надо пересобрать. Не обновить сервер. Пересобрать.

Причина скучная и потому неприятная: приватные ключи восьми промежуточных CA eMudhra оказались меньше 256. Среди значений, которые потом обсуждали публично, были 4, 56 и 115. Нормальный приватный ключ для P-384 это случайное число длиной около сотни десятичных цифр. Ключ длиной в три цифры восстанавливается из публичного сертификата перебором на ноутбуке. Дальше владелец такого ключа выпускает валидный TLS-сертификат на любой домен, и клиент, доверяющий корню eMudhra или кросс-подписи Sectigo, его примет. Это готовый перехват трафика, без взлома и без эксплойта.

Хроника: четыре дня от сигнала до релиза

Дата (2026)Что произошло
17 октябряИсследователь пишет Apple, Google, Microsoft, Mozilla и самой eMudhra. Mozilla в тот же день сама восстанавливает ключи и блокирует восемь промежуточных CA через OneCRL. Chrome блокирует их в день сообщения.
18 октябряeMudhra отзывает сертификаты.
19 октябряПодключается Apple. Выходят Go 1.27.3 и 1.26.10.
20 октябряMicrosoft. Утром независимые исследователи раскрывают слабость ключей публично.
26 октябряRoland Shoemaker из команды безопасности Go публикует разбор инцидента.
27 октябряУдаление корня eMudhra из Chrome Root Store доходит до пользователей.

Внутри 19 октября всё уложилось в один рабочий день по тихоокеанскому времени. В 11:45 внешний исследователь сообщает Go Security о неанонсированных действиях Mozilla. В 12:30 Mozilla пишет сама и просит не раскрывать детали, но выпустить патч как можно скорее. К 14:00 патч готов, исследователь присылает тестовые сертификаты, подписанные восстановленными ключами. В 15:00 начинается выпуск, в 19:13 релиз опубликован. Сама сборка и публикация заняли чуть больше четырёх часов.

Анонс намеренно сделали расплывчатым: Go «блокирует доверие небольшому набору промежуточных сертификатов из-за конкретных проблем с их эксплуатацией». Защищающиеся получили сигнал обновиться. Атакующие не узнали, что именно искать.

«Слабый» здесь значит буквально следующее: каждый из восьми приватных ключей меньше 256.

Что было до: у Go не было режима «срочно»

Политика безопасности Go знала два трека. PUBLIC для мелочей, которые чинят в обычных минорных релизах. PRIVATE для серьёзных уязвимостей: исправление готовят закрыто, релиз анонсируют за 3–7 дней. Такой график работал годами, потому что у админов было время на планирование окна обновления.

Случай eMudhra в это окно не влезал. Ключ, который восстанавливается за микросекунды, не ждёт неделю приватной подготовки. Появился трек URGENT: ситуация, когда эксплуатация вот-вот начнётся и предупреждать заранее некогда. Релиз 19 октября стал первым прогоном этого трека, и первый блин показал узкие места релизного процесса. Пока выпуск занимал дни, они не мешали. Теперь мешают, и команда их устраняет.

Одно предложение из разбора стоит внимания: анонсировать URGENT-релизы в момент старта процесса, чтобы у пользователей оставалось хотя бы несколько часов на подготовку. Практический вывод простой. Подпишитесь на golang-announce. Если ваш сервис собран на Go, рассылка про новые версии перестаёт быть шумом.

Почему на Linux нечем было закрыть дыру

Проверка сертификатов в Go зависит от платформы, и это ключевая деталь всего сюжета.

На Windows и macOS crypto/x509 передаёт проверку цепочки системе, через CryptoAPI и Security.framework. Когда Microsoft и Apple выкатили отзыв, Go-программы получили его сами, без пересборки.

На Linux системного API для проверки цепочек нет. Go берёт корни из системного хранилища (/etc/ssl/certs/...) и проверяет цепочку своим верификатором внутри бинарника. Списки отзыва CRL и OCSP он не проверяет. Значит, никакой отзыв сертификата на уровне ОС на Go-программу не действует. Закрыть дыру можно было только новым рантаймом, который жёстко запрещает цепочки через скомпрометированные промежуточные CA.

Обновление пакета ca-certificates помогает частично. В Debian исправление вышло (20250419+deb13u1 для trixie, 20250419~deb12u2 для bookworm). В distroless- и scratch-образах, куда хранилище корней скопировано на этапе сборки, обновлять нечего: образ придётся пересобрать.

Кому что делать

Где крутится сервисДействие
Windows, macOSОтзыв приходит с обновлением ОС. Пересборка не обязательна, но версию тулчейна всё равно проверьте.
Linux, обычный образПересобрать бинарники на Go 1.27.3 / 1.26.10 или новее. Обновить ca-certificates.
Distroless, scratchПересобрать образ: корни вшиты на этапе сборки.
Go 1.25 и раньшеИсправления не будет. Апгрейд тулчейна и пересборка.

Обновить рантайм на сервере недостаточно

Вот та самая мысль, ради которой стоит читать этот разбор целиком. Верификатор зашит в бинарник. Пока вы не пересобрали сервис новым тулчейном, в нём живёт старый код, доверяющий слабому промежуточному CA. Пропатченный Go на соседней машине вашего бинарника не касается.

Пересобирать нужно всё, что ходит по TLS: напрямую через net/http и crypto/tls, через gRPC, через SDK облаков, через драйверы баз данных. Внешне это выглядит как рутина про «обновите зависимости», а по факту это инвентаризация всего, что вы собираете и куда деплоите.

  1. Проверьте, чем собран бинарник. go version -m ./bin/my-service покажет тулчейн, которым он собран. go version покажет версию на машине сборки.
  2. Прогоните govulncheck по готовым бинарникам, не по исходникам: GOTOOLCHAIN=go1.27.3+auto go install golang.org/x/vuln/cmd/govulncheck@latest, затем govulncheck -mode=binary ./bin/my-service. Проверка по артефакту ловит то, что исходники уже не помнят.
  3. Пройдитесь по парку разом. Обход каталогов с go version по каждому файлу и сортировкой по версии даёт список того, что отстало. Для десятка сервисов это минуты, для сотни — вечер, зато без догадок.
  4. Пересоберите базовые образы и прогоните CI заново. Образ, собранный полгода назад, содержит ровно те корни, которые были полгода назад.

Отдельно про масштаб. В логах Certificate Transparency сертификатов, выпущенных шестью TLS-интермедиатами eMudhra, нет. Активной эксплуатации на момент разбора не обнаружено. Это не повод расслабиться: отсутствие следов в CT и отсутствие атаки это разные вещи, а ключ, который перебирается за секунды, оставляет мало следов.

Где подвох

Первый риск связан с самим треком URGENT. Если такие релизы станут нормой, обновление Go превратится из планового события в пожарную тревогу. Инженерная команда из трёх человек не может жить в режиме «патч вышел в 19:13, пересобери всё до утра». Значит, нужен регламент: кто читает golang-announce, кто собирает список бинарников, кто отвечает за пересборку в нерабочее время. Без этого срочный релиз рантайма превращается в срочный простой.

Второй риск в иллюзии «мы обновили систему». Обновлённый ca-certificates в Debian, свежий пакет в apt, зелёный статус в мониторинге. На Linux этого мало, и это неочевидно для тех, кто привык к миру, где проверка цепочек делегирована ОС.

Третий риск: кросс-подписи. У каждого из восьми промежуточных CA eMudhra была кросс-подпись от корня Sectigo AAA Certificate Services. Простое удаление корня eMudhra ничего не решает, потому что цепочка сойдётся через Sectigo. Именно поэтому Go блокировал не корень, а сами промежуточные сертификаты по SPKI.

Четвёртый: старые версии. Go 1.25 и более ранние исправления не получат вообще. Если у вас на проде сервис, собранный три года назад и с тех пор не трогавшийся, у него нет ни патча, ни плана апгрейда. Это отдельная задача, и она не решается в день инцидента.

Вердикт

Семь с половиной часов от сообщения до релиза это хорошая новость про мейнтейнеров Go и плохая новость про процессы у всех остальных. Рантайм теперь отвечает за безопасность за часы. Ваша инфраструктура отвечает за пересборку за дни, недели или никогда.

Что делать на этой неделе, без героизма. Подписаться на golang-announce. Прогнать go version -m по всем своим бинарникам и увидеть реальную картину: сколько из них собрано на версиях, которые уже не получат патчей. Завести привычку хранить версию тулчейна в метаданных релиза, чтобы в следующий раз не искать её по сусекам. Пересобрать сервисы на 1.27.3, 1.26.10 или новее. Для distroless-образов запланировать пересборку отдельным пунктом, а не «когда будет время».

И держать в голове простое правило. ОС можно обновить. Бинарник Go можно только пересобрать. Пока вы этого не сделали, в проде работает старый верификатор со старыми довериями, и никакой патч на сервере этого не изменит.

Читайте также