Bollywood HungamaRamayana producer Namit Malhotra calls Los Angeles premiere his “Oscar moment” ahead of November 5 releaseEl ComercioLa hoja de ruta de Estados Unidos para Venezuela: reformas, vacancia de Delcy Rodríguez y eleccionesPunchBREAKING: NELFUND introduces token system to stop double payment of school feesThe Jerusalem PostQatari mediators present peace deal to Iran in mediation effort, official saysInquirer EntertainmentDonny Pangilinan felt ‘awkward’ over Showtime Baby Doll Juby’s dream about himDaily MaverickWildlife is not livestock — Aucamp’s dangerous plan to turn conservation into agricultureInquirerMimaropa drug bust in Palawan yields ₱51,884 worth of ‘shabu’ZDF heuteEntdecken Sie das ZDF-NachrichtenstudioSky TG24Meteo, freddo e maltempo in Italia nel weekend di Halloween e Ognissanti. Le previsioniVariety‘One Cut of the Dead’ Director Ueda Shinichiro on Turning a Microdrama Into Tokyo Feature ‘Earthlings in Love’NumeramaÀ mi chemin entre le VTC et le longtail, le vélo électrique Nakamura Crosscity+ perd 500 €DeadlineRussell Brand Forcefully Denies Charges As He Gives Evidence During Rape Trial
The Daily Newsstand · Free, Always
Wednesday, October 28, 2026

Разбираем три самые интересные уязвимости Spring за июнь

Translate

В июне 2026 года был опубликован список из 71 уязвимости в экосистеме Spring. Из них 31 получила уровень опасности High, 36 — Medium и четыре — Low. Для сравнения: за весь 2025 год было обнаружено 16 уязвимостей.

Из общего списка уязвимостей мы выбрали три, в которых сочетаются относительно понятный путь до уязвимого кода и серьёзные последствия. Нас интересовало, как ошибка проявляется в распространённых сценариях: при обработке JSON Patch, аутентификации через LDAP и передаче сообщений через Kafka.

Разберём чуть подробнее три самые интересные уязвимости по соотношению «достижимость × последствия»:

  1. CVE-2026-41729 — SpEL-инъекция через ключ Map в JSON Patch (Spring Data REST).

  2. CVE-2026-41720 — обход аутентификации пустым паролем в Spring LDAP (unauthenticated bind).

  3. CVE-2026-41731 — небезопасная десериализация заголовков в Spring for Apache Kafka (префиксное сопоставление доверенных пакетов).

1. CVE-2026-41729: SpEL-инъекция через ключ Map в JSON Patch

CVSS 3.1: AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N

В чём суть

Spring Data REST принимает JSON Patch (RFC 6902) с Content-Type: application/json-patch+json. Каждая операция патча (add, replace, test и т.д.) задаёт путь к полю в формате JSON Pointer. Когда сохраняемый объект (корневой агрегат) содержит свойство-Map, сегмент пути JSON Pointer трактуется как ключ Map и без экранирования подставляется в SpEL-выражение для обращения к значению по этому ключу. Специально сформированный ключ нарушает структуру выражения metadata['<ключ>']: закрывает строковый литерал раньше времени и позволяет добавить другое SpEL-выражение, которое будет вычислено в контексте корневого агрегата.

Затронуты оба пути обработки: чтение (когда патч обращается к текущему значению) и запись (когда патч изменяет данные).

Класс ошибки — CWE-917 (недостаточная нейтрализация специальных элементов при построении выражения).

Технический механизм

Для обычного объекта путь /profile/name преобразуется в последовательность обращений к Java-свойствам (profile.name). Если свойство имеет тип Map, к его значению нужно обратиться по ключу:

Путь JSON Pointer:   /metadata/<map-key>

Выражение SpEL:      metadata['<map-key>']

Проблема в том, что <map-key> не экранируется перед тем, как попасть внутрь строкового литерала '...':

Ключ (ожидание):        "config"

Результат:              metadata['config']

Ключ (атака):           "x'] + T(java.lang.System).getProperty('os.name') + ['"

Результат (уязвимо):    metadata['x'] + T(...).getProperty('os.name') + ['']

                        └─ вне намеренного ключа вычисляется произвольный SpEL-код

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

Поток данных при атаке:

HTTP PATCH

  → Content-Type: application/json-patch+json

  → разбор операций JSON Patch

  → извлечение пути (JSON Pointer)

  → определение, что свойство имеет тип Map

  → построение конструкции metadata['<ключ>'] без экранирования ключа Map

  → вычисление SpEL в контексте корневого агрегата

  → чтение или изменение данных за пределами намеренного ключа

Ущерб для организации

  • Доступ к данным за пределами указанного ключа — выражение вычисляется в контексте всего корневого агрегата, поэтому доступны все его поля и вложенные объекты, даже не предназначенные для выдачи (C:H).

  • Несанкционированное изменение данных — путь записи позволяет менять не те поля, которые указаны в патче, в том числе в обход ограничений «только для чтения» модели (I:H).

  • Потенциальное выполнение кода — при наличии в контексте вычисления полезных классов выражение может дойти до вызова произвольных методов JVM (вектор RCE-класса).

  • Высокая достижимость — триггер не требует разработки специфичного кода: достаточно обычной модели с Map-полем и стандартного Spring Data REST, поэтому уязвимых приложений много, а барьер атаки AC:L/PR:L низкий.

  • Для организации: утечка персональных данных (инцидент по 152-ФЗ, уведомление регулятора, штрафы), тихая порча доменных данных (позднее обнаружение через аудит, а не через атаку), мошенничество при компрометации платёжных/залоговых полей.

Итог: самая опасная из трёх по последствиям — потеря конфиденциальности и целостности на высоком уровне с низким порогом эксплуатации, при том что JSON Patch открыт по умолчанию. Усугубляется тем, что первый шаг эксплуатации не является явной аномалией для центра мониторинга информационной безопасности.

2. CVE-2026-41720: обход аутентификации пустым паролем в Spring LDAP

CVSS 3.1: AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N

В чём суть

Реализации DirContextAuthenticationStrategy в Spring LDAP не отклоняют bind-запрос, в котором указано непустое имя пользователя в паре с пустым (null) паролем. По RFC 4513 §5.1.2 такой запрос называется unauthenticated bind: клиент сообщает имя, но не предъявляет секрет. Если LDAP-сервер разрешает такой bind, проверка пароля фактически не выполняется.

Ранний аналог в Spring Security — CVE-2014-0079 (та же первопричина: empty-password bind прошёл проверку).

Технический механизм

Протокол LDAP различает три случая:

Bind-запрос

Пароль

Семантика

Пустой DN

пустой

Анонимный доступ (anonymous)

Непустой DN

пустой

Unauthenticated bind

Непустой DN

непустой

Обычная проверка пароля

Сервер с ослабленной конфигурацией (например, разрешённый allow bind anon dn в OpenLDAP / 389 DS) может признать unauthenticated bind успешным, не проверив пароль. Spring LDAP на клиенте воспринимает успешный bind как успешную аутентификацию и не сверяет «пароль был» — стратегия просто не фильтровала пустой пароль до отправки запроса.

Уязвимый путь затрагивает все способы аутентификации через:

  • AbstractContextSource (и его наследники DefaultSpringSecurityContextSource);

  • LdapTemplate.authenticate(...);

  • LdapClient.authenticate(...).

Поток атаки:

Атакующий знает имя пользователя (admin / сервисный аккаунт / пользователь)

  → отправляет bind:  dn=uid=<username>,ou=...,dc=corp  password=""

  → Spring LDAP не отбрасывает запрос как «пустой пароль»

  → сервер выполняет unauthenticated bind и возвращает success

  → приложение считает пользователя аутентифицированным

Ущерб для организации

  • Компрометация корпоративного поставщика идентификации — LDAP часто обслуживает всю экосистему: одну атаку можно переиспользовать против любого подключённого приложения.

  • Доступ под привилегированными учётками — сервисные и админ-аккаунты становятся самой привлекательной целью, т.к. не привязаны к человеческим процессам MFA/смены пароля.

  • Отсутствие следов — аутентификация формально «успешна», события входа не содержат признаков аномалии; SIEM и блокировки по числу неудачных попыток не срабатывают (попытка не «неудачная»).

  • Латеральное движение и долгое присутствие — сессия от имени легитимного пользователя позволяет спокойно обходить продуктовую защиту приложений.

Итог: критичность в слое идентификации, как только сервер разрешает unauthenticated bind.

3. CVE-2026-41731: небезопасная десериализация заголовков в Spring for Apache Kafka

CVSS 3.1: AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H

В чём суть

JsonKafkaHeaderMapper и устаревший DefaultKafkaHeaderMapper сопоставляли заголовки типа сообщения со списком «доверенных пакетов» по префиксу: доверие одному пакету автоматически означало доверие всем его подпакетам. В сочетании со стандартной Jackson-десериализацией бинов продюсер мог подложить в заголовок имя произвольного JDK-класса — консьюмер десериализовал его, включая классы, чьи конструкторы несут побочные эффекты (выделение файловых дескрипторов, создание пулов потоков).

Класс ошибки — CWE-502 (десериализация недоверенных данных) с первопричиной «некорректная проверка доверенного диапазона по префиксу».

Технический механизм

Spring for Apache Kafka передаёт информацию о типе через заголовки сообщения: TypeId, KeyTypeId, ContentTypeId. Тип-информацию из этих заголовков читают оба механизма JSON-десериализации:

  • JsonDeserializer — низкоуровневый десериализатор консьюмера (spring.kafka.consumer.value-deserializer) — снимает заголовок напрямую;

  • JsonMessageConverter (например, ByteArrayJsonMessageConverter) — преобразователь уровня контейнера прослушивания, за которым уже стоит байтовый десериализатор.

Оба пути проверяют указанный в заголовке класс против списка доверенных пакетов через маппер заголовков (JsonKafkaHeaderMapper или устаревший DefaultKafkaHeaderMapper).

Уязвимость в логике проверки:

Доверенные пакеты (конфигурация):   com.example.app

Проверка по префиксу (уязвимо):     com.example.app.SomeType  → OK

                                    com.example.appx.Evil    → OK (префикс совпал!)

                                    java.lang.ThreadPool     → OK, если доверен java.*

                                    java.io.FileOutputStream → OK, если доверен java.

Доверие по префиксу означает: если в списке есть com.example или (частая практика) java.util, java.io, java.lang либо корневой пакет приложения, то «пропускается» весь диапазон подпакетов — включая стандартные библиотечные классы JVM. Дальше работает десериализация по умолчанию: Jackson инстанцирует указанный класс через конструктор, а любой класс с побочным эффектом в конструкторе выполняет его прямо при чтении сообщения.

Поток атаки:

Продюсер (недоверенный, имеет доступ на запись в топик)

  → публикует сообщение с заголовком TypeId: java.io.FileOutputStream / java.util.concurrent.ScheduledThreadPoolExecutor ...

  → Kafka доставляет сообщение в консьюмер (@KafkaListener)

  → JsonKafkaHeaderMapper проверяет заголовок типом против доверенных пакетов по префиксу

  → проверка проходит («доверен java.*»)

  → Jackson создаёт экземпляр указанного класса

  → побочный эффект конструктора срабатывает в процессе консьюмера

Ущерб для организации

  • RCE-класс при широком доверенном диапазоне — десериализация произвольных типов в процессе JVM (C:H/I:H/A:H): чтение/изменение данных на узле консьюмера и потенциальное исполнение кода.

  • Латентность и «вслепую» — сообщение лежит в топике и срабатывает в момент обработки любым из потребителей; источник отделён во времени от последствия, что сильно затрудняет связывание инцидента с конкретным событием.

  • Каскадный охват — в событийно-ориентированной архитектуре один скомпрометированный продюсер отравляет сообщения всем консьюмерам топика сразу: неделя расследований вместо одного запроса.

  • Тихий отказ в обслуживании через ресурсы — исчерпание файловых дескрипторов или потоков выглядит как падение производительности «на ровном месте», а не как атака.

  • Для организации: в микросервисной Spring-системе Kafka — ядро обмена, поэтому доверенный контур «производители → топик → потребители» должен быть строгим; размытие этой границы из-за широких доверенных пакетов обнуляет изоляцию сервисов.

Итог: самый «серьёзный по классу» вектор из трёх — десериализация недоверенных данных с потенциальным RCE у каждого потребителя, что особенно критично для событийно-ориентированных архитектур, где Kafka является системообразующим компонентом.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.