MaxKB: путь диспетчеризации агентов позволяет пользователю, которому заблокирован инструмент, все равно вызывать его и читать его учетные данные

Источник: OrcaRouter•

MaxKB: путь диспетчеризации агентов позволяет пользователю, которому заблокирован инструмент, все равно вызывать его и читать его учетные данные

Участник рабочего пространства MaxKB с минимальной ролью, которому заблокирован инструмент, все равно мог привязать и запустить его через путь агента или рабочего процесса, получая его расшифрованные учетные данные.

MaxKB, корпоративный ИИ-ассистент с открытым исходным кодом, поддерживаемый 1Panel-dev, поставляется со списком разрешений для каждого пользователя и каждого инструмента, чтобы администратор мог предоставить участнику рабочего пространства один инструмент и запретить другой. Согласно рекомендациям по безопасности, опубликованным 2 сентября 2026 года, этот запрет действовал для собственных маршрутов инструмента, но не для пути, который агент или рабочий процесс использует для вызова того же инструмента. Участник рабочего пространства с минимальной ролью мог указать идентификатор запрещенного инструмента при создании рабочего процесса, запустить рабочий процесс и получить не только вывод инструмента, но и учетные данные, которые MaxKB расшифровывает на стороне сервера для его запуска. Затронуты версии с 2.0.0 по 2.9.2, а в бюллетене безопасности не указано ни одной исправленной версии. Эта запись — обход авторизации диспетчеризации инструментов в MaxKB — является одной из записей в архиве инцидентов ИИ OrcaRouter, который содержит полный набор записей и соседние с этим инцидентом записи.

Что заставляет внимательно изучить этот случай, так это не оценка. Дело в том, что в продукте уже была правильная проверка, она применялась на очевидной двери и оставляла вторую дверь к той же возможности без присмотра. Рекомендация GHSA-383v-fx78-pphm была написана исследователем, обнаружившим уязвимость, и опубликована через систему рекомендаций GitHub 2 сентября 2026 года в 07:43 UTC, с указанием авторства Маттео Панцери (@matte1782). Запись CVE, CVE-2026-77516, последовала 21 сентября 2026 года.

Что устанавливает бюллетень

Модель MaxKB для каждого инструмента называется WorkspaceUserResourcePermission и описывается в бюллетене как список разрешений по умолчанию с запретом, разрешаемый во время запроса. Выделенные маршруты инструментов обеспечивают ее соблюдение. В бюллетене принудительное применение перечислено в apps/tools/views/tool.py, где Operate.put, Operate.get, Debug.post, Export.get и Delete выполняют проверку прав просмотра в отношении разрешений инструментов рабочего пространства вызывающего абонента. Debug.post — это маршрут, наиболее близкий к простому запуск инструмента, и он защищен.

Путь диспетчеризации агентов и рабочих процессов не повторяет эту проверку. В бюллетене прослеживаются три отдельные точки, где она отсутствует. В apps/application/serializers/application.py сериализатор приложения привязывает tool_ids, skill_tool_ids и mcp_tool_ids напрямую из входных данных запроса без авторизации для каждого инструмента — и в бюллетене отмечается, что асимметрия видна в том же файле, поскольку knowledge_id_list проверяется на соответствие доступным пользователю базам знаний на несколько строк ниже, а инструменты — нет. В apps/common/utils/shared_resource_auth.py функция filter_authorized_ids без каких-либо условий пропускает каждый инструмент в собственном рабочем пространстве вызывающего абонента; шлюз между рабочими пространствами, на который она опирается, является хуком только для корпоративной версии, отсутствующим в сообщественной редакции, и она никогда не обращается к WorkspaceUserResourcePermission. А на конечном этапе apps/application/flow/step_node/tool_lib_node/impl/base_tool_lib_node.py запускает сохраненный код инструмента с его init_params, расшифрованными с помощью rsa_long_decrypt под идентичностью приложения, без проверки разрешений для каждого инструмента.

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

Демонстрация в цифрах исследователя

В бюллетене сообщается о динамическом подтверждении в версии v2.9.2, запущенной из официального универсального образа 1panel/maxkb:v2.9.2. Настройка состояла из одного рабочего пространства, администратора и второго участника с ролью USER. Администратор создал Инструмент А и Инструмент Б, поместил свежий случайный секрет в init_params Инструмента Б и написал тело Инструмента Б так, чтобы оно возвращало этот секрет при выполнении. Затем участнику было предоставлено разрешение для каждого инструмента только на Инструмент А, и в бюллетене говорится, что состояние нулевых привилегий для Инструмента Б было повторно проверено в базе данных после запуска.

Запрещенная половина теста вернула то, что обещает продукт. Для участника маршрут отладки для Инструмента Б ответил кодом 403, маршрут обновления — 403, маршрут экспорта — 403, а разрешенный Инструмент А вернул 200 в качестве проверки работоспособности. Затем в рамках второй половины обхода Инструмент Б был привязан к приложению рабочего процесса через узел библиотеки инструментов — привязка была принята с HTTP 200 и без проверки каждого инструмента, а запуск рабочего процесса вернул HTTP 200 с телом, содержащим имя инструмента, секрет-маяк и список ключей ["api_key"].

В бюллетене говорится, что секрет проявился на трех уровнях: в ответе API рабочего процесса, в записи выполнения инструмента со статусом SUCCESS и в строке базы данных, где init_params Инструмента Б находятся в виде зашифрованного текста RSA размером 344 байта, что служит аргументом исследователя о том, что значение было расшифровано на стороне сервера под идентичностью приложения, а не предоставлено вызывающим абонентом. Тот же участник, которому было отказано на маршруте запуска инструмента, получил расшифрованный секрет инструмента, привязав его к рабочему процессу.

Одна оценка опубликована, за другую идет спор

Оценка, привязанная к CVE-2026-77516, составляет CVSS 3.1 5.4, средняя (Medium), с вектором AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N. Запись в NVD показывает, что эта оценка получена из ленты рекомендаций GitHub, а не из собственного анализа NVD, и запись имеет статус Deferred (Отложено), что означает, что NVD ее не дополняла. Собственная классификация архива следует этой опубликованной оценке: средняя степень серьезности, реальный ущерб не зафиксирован.

В разделе о влиянии в самом бюллетене приводятся аргументы в пользу более высокой оценки. В нем указана степень серьезности 7.1, высокая (High), для вектора, который повышает влияние на конфиденциальность до высокого, и говорится, что этот показатель возрастает до 8.1, когда задействованный инструмент выполняет привилегированные записи под идентичностью приложения. Это разногласие по поводу того, как оценивать раскрытие учетных данных, а не по поводу того, существует ли обход — в том же документе и демонстрируется уязвимость, и утверждается, что ее недооценивают. Ничто в общедоступных записях не разрешает вопрос о том, какая цифра верна, а средний рейтинг архива отражает опубликованную оценку CVE, а не аргументы бюллетеня.

В записях зафиксированы еще две оценки. Решения SSVC CISA, добавленные в запись NVD 28 сентября 2026 года, фиксируют эксплуатацию как «poc», возможность автоматизации как «нет» (no) и техническое воздействие как «частичное» (partial) — значение «poc» отражает наличие концептуального доказательства (proof of concept), которое действительно существует в самом бюллетене; это не является констатацией эксплуатации «в дикой природе». Модель EPSS организации FIRST оценивала вероятность эксплуатации в следующие 30 дней в 0.242%, на уровне 15.2-го перцентиля, в оценке от 27 октября 2026 года.

Исправление, появившееся раньше бюллетеня, и отсутствие исправлений в затронутом диапазоне

В таблице версий бюллетеня указаны затронутые версии с 2.0.0 по 2.9.2, исправленные версии отсутствуют, а в тексте говорится, что по состоянию на момент проверки исправленная версия недоступна, при этом добавляется, что исправление в помеченном выпуске позволило бы привязать к нему CVE. Репозиторий вендора рассказывает немного другую историю, и эта разница важна для всех, кто решает, что запускать.

В репозитории MaxKB функции, закрывающие путь диспетчеризации — validate_bound_tool_permissions и get_authorized_tool_ids в apps/application/serializers/application.py — отсутствуют в теге v2.9.2, а также в v2.10.2-lts, v2.10.3-lts и v2.10.4-lts, но присутствуют начиная с версии v2.10.5-lts и далее. Этот релиз был опубликован 6 августа 2026 года, за четыре недели до публикации бюллетеня. Тот же тег добавляет проверку инструментов для каждого пользователя в base_tool_lib_node.py с использованием WorkspaceUserResourcePermission, а также добавляет фильтр с учетом пользователей в shared_resource_auth.py — то есть в общих чертах реализует три исправления, которые впоследствии рекомендует бюллетень.

Никто не заявлял об этой связи публично. В примечаниях к релизу v2.10.5-lts не упоминается исправление разрешений на инструменты; в них перечислены четыре не связанные с этим вопроса безопасности, а также набор работ по функциям и исправлениям ошибок. В бюллетее не упоминается версия 2.10.5, а затронутый диапазон просто заканчивается на v2.9.2 — последнем релизе линейки 2.9. История релизов не содержит патчей для ветки 2.9.x после выпуска бюллетеня, поэтому развертывание версии 2.9.2 не имеет исправленной сборки в пределах собственной линейки. Текущим релизом является v2.10.8-lts, опубликованный 22 октября 2026 года, в примечаниях к которому описываются исправления X-Pack для авторизации общих инструментов, а не что-либо в пути диспетчеризации community-редакции.

Что не установлено

Три вещи стоит отделить от демонстрации. Во-первых, нет никаких публичных сообщений об использовании этого обхода против кого-либо. В материалах фигурирует найденная уязвимость, а не расследованный инцидент проникновения; здесь нет пострадавших, нет приписанных кому-либо злоумышленников и нет ущерба, а доказательство концепции из бюллетеня было запущено исследователем в изолированном рабочем пространстве. во-вторых, ни одно новостное издание, регулятор или вторая исследовательская группа, судя по всему, не анализировали эту уязвимость: существующее освещение ограничивается базами данных уязвимостей и агрегаторами — среди которых VulDB, база данных Rapid7, Armis, SOCRadar и openCVE — которые перечисляют CVE и содержат описание из бюллетеня, но ни один из них не предлагает независимую оценку кода. Механизм, описанный здесь, опирается исключительно на один бюллетень и собственный исходный код вендора. В-третьих, нет никаких данных о том, сколько инсталляций MaxKB находится в затронутом диапазоне, и ни вендор, ни исследователь не публиковали подобных цифр.

Группа риска невелика, но ее трудно подсчитать: это самостоятельно развернутые установки community-редакции MaxKB версий с 2.0.0 по 2.9.2, имеющие более одного участника рабочего пространства, где администратор использовал разрешения для конкретных инструментов, чтобы скрыть инструмент, содержащий учетные данные. Уязвимость не является удаленным выполнением кода и требует наличия действительной учетной записи с низкими привилегиями, поэтому влияние на конфиденциальность определяет оценку, а не путь атаки. То, что получает злоумышленник, ограничено тем, к чему имеют доступ заблокированные инструменты — ключи API, токены и все, что они открывают, — и именно поэтому авторы бюллетеня утверждают, что масштаб последствий выше, чем подразумевает низкий рейтинг конфиденциальности.

Что может сделать оператор

Рекомендации бюллетеня адресованы сопровождающим, а не операторам, и его три шага соответствуют коду, появившемуся в v2.10.5-lts: применять разрешение для конкретного инструмента перед выполнением инструмента в библиотеке инструментов и в реализациях узлов инструментов, проверять все привязанные tool_ids, skill_tool_ids и mcp_tool_ids во время привязки точно так же, как это уже делается для knowledge_id_list, и заставить filter_authorized_ids проверять разрешения для конкретных инструментов, а не только принадлежность к рабочему пространству.

Для команды, использующей затронутую сборку, практические шаги, вытекающие из описания в самом бюллетене, заключаются в следующем.

• Считать каждый секретный ключ, сохраненный в параметрах init_params инструмента в затронутой системе, доступным любому участнику рабочего пространства, включая самую низкую роль, и заменить эти учетные данные, а не полагаться на то, что ограничение доступа к конкретным инструментам защитило их.

• Провести аудит состава участников рабочего пространства. Для обхода требуется аутентифицированная учетная запись в рабочем пространстве, поэтому удаление неактивных или ненадежных участников снижает риски даже там, где код невозможно пропатчить.

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

• При обновлении следует учитывать, что проверка конкретного пользователя появляется в репозитории начиная с версии v2.10.5-lts и что ни один релиз не назван бюллетенем в качестве исправления — оператор, полагающийся на обновление, опирается на помеченный тегом исходный код, а не на заявление вендора о выпуске патча.

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

Урок этой истории носит скорее структурный, чем количественный характер. Разрешение для конкретного ресурса надежно ровно настолько, насколько надежна точка входа с наименьшей защитой, а платформа агентов быстро накапливает точки входа: отладочный маршрут, маршрут экспорта, узел рабочего процесса, триггер чата. У MaxKB были список разрешений и проверка; чего ей не хватало для ветки с 2.0 по 2.9, так это привычки задавать один и тот же вопрос у каждой двери.

О чём эта статья

Ещё в разделе «AI и машинное обучение»

Все →

Ещё от OrcaRouter