Проверка сертификатов в wolfSSL пропускает поддельные удостоверяющие центры

wolfSSL

Криптографическая библиотека wolfSSL, отвечающая за защищённые соединения в nginx, haproxy, stunnel, Apache httpd, BIND, rsyslog, ffmpeg и wpa_supplicant, содержит одиннадцать уязвимостей. Три из них вендор отнёс к высокому уровню угрозы, четыре к среднему и четыре к низкому. Почти все ошибки бьют по одному узлу - проверке сертификата собеседника. Уязвимые сборки выходили до версии 5.9.4 включительно.

Детали уязвимостей

Первая уязвимость высокой степени опасности получила номер CVE-2026-93302. Она затрагивает механизм доверенных сертификатов равноправных узлов. Когда приложение заранее перечисляет удостоверяющие центры, которым доверяет, библиотека сверяет только имя сертификата. Открытый ключ внутри него при проверке не учитывается. Поэтому копия удостоверяющего центра с тем же именем, но чужим ключом проходит как настоящая.

Для атаки требуется знать, какие именно центры загружает клиент. В типовых развёртываниях этот перечень предсказуем, а иногда его выдают открытые конфигурации. Если сборка включает ещё и режим совместимости с OpenSSL, под удар попадает любая загрузка удостоверяющих сертификатов, а не только явный список доверенных узлов. Тогда поддельный сервер обходит аутентификацию полностью. Схемы взаимной проверки, где клиент и сервер подтверждают подлинность друг друга, тоже не спасают, если клиент знает набор центров, загруженных на стороне сервера.

Вторая уязвимость высокого уровня, CVE-2026-89102, касается клиентов, которые запрашивают у сервера несколько закреплённых ответов протокола онлайн-проверки отзыва сертификатов (OCSP). Клиент принимает любой сертификат из цепочки собеседника за удостоверяющий центр и не проверяет, вправе ли тот их выдавать. Значит, владелец обычного сертификата от доверенного центра вместе с закрытым ключом может подделать удостоверение на любое имя. Последствия не ограничиваются одним соединением. Сертификат конечного узла оседает в постоянном хранилище доверия, поэтому следующие подключения с тем же контекстом тоже считают его законным.

Третья ошибка высокого уровня связана с режимом необработанных открытых ключей (RPK), который заменяет сертификаты парой ключей. Клиент TLS 1.2, TLS 1.3 и DTLS 1.2, где DTLS означает защищённый протокол поверх датаграмм, принимает незапрошенный серверный тип ключа и пропускает проверку подлинности. Режим по умолчанию выключен. Его включают флаги --enable-rpk, --enable-all и --enable-distro.

Четыре уязвимости помечены средним уровнем. Одна из них позволяет клиенту (D)TLS 1.2 принять служебное сообщение о смене шифра раньше положенного срока, ещё до выработки общего секрета. Ключи чтения в этот момент выводятся из известного значения, и проверка финального сообщения сервера идёт по нему же. Атакующий в позиции "человек посередине" завершает рукопожатие вместо настоящего сервера и отправляет данные, которые клиент считает подлинными. Свой трафик клиента остаётся закрытым, а настоящий сервер рукопожатие не заканчивает. В DTLS 1.2 достаточно одной датаграммы с записями не по порядку. В TLS 1.2 нужен либо режим упреждающего чтения, либо ручная передача уже принятых байтов в библиотеку. Для соединений с предварительно распределённым ключом поддельный сервер справляется, вообще не зная этого ключа.

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

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

Исправления вышли в коммите 22bcd51 и нескольких наборах правок, они войдут в ближайший релиз ветки. Обновиться стоит всем, кто собирает библиотеку со включённым режимом совместимости с OpenSSL, поскольку он расширяет зону поражения. Смягчить первую уязвимость помогает флаг --disable-openssl-compatible-defaults и отказ от загрузки удостоверяющих центров через механизм доверенных узлов. Помимо этого, заменить файлы библиотеки недостаточно. Отравленные записи живут в общих хранилищах, привязанных к контексту соединения, поэтому длительно работающий процесс придётся перезапустить целиком.

Слабые места в проверке сертификатов перестали быть редкостью для встраиваемых TLS-библиотек. Их код идёт в маршрутизаторы, промышленные контроллеры и облачные балансировщики, а собирают его десятками разных способов. Часть найденных ошибок всплыла в ходе программы Anthropic по аудиту открытого кода, то есть речь не о единичной оплошности, а о системной теме. Отсюда практический вывод: проверять надо не только версию библиотеки, но и набор флагов сборки. Ошибка, безобидная в одном дистрибутиве, в другом открывается одним параметром конфигурации.

Ссылки

Комментарии: 0