MLSecOps-скан: как найти все ИИ-активы в репозитории и проверить их до релиза
С появлением ИИ вопрос «что у нас в проде» усложнился. Когда мы говорим о безопасности приложений, у нас уже есть устоявшийся набор инструментов: SAST смотрит на код, SCA на зависимости, Secrets на утечки ключей, DAST на работающее приложение. Но как только в продукте появляется ИИ-компонент (агент, модель, векторное хранилище, датасет), то привычные сканеры перестают отвечать на главный вопрос: из чего вообще состоит эта ИИ-система и какие у неё дефекты?
ИИ-модель – это не просто файл с весами. Это адаптеры, промпты, MCP-серверы, конфигурации инференса, обучающие данные, ML-библиотеки, ноутбуки и пайплайны. Каждый из этих элементов – потенциальная точка отказа и потенциальный вектор атаки. И, что важнее, большинство из них никто не объявлял: они появились в репозитории «сами собой», и о них не знает ни CISO, ни AppSec-команда.
В этой статье разберём, как MLSecOps-сканер, встроенный в INFERA AI.SafeCode, определяет состав ИИ-системы, какие дефекты он ищет и почему реестр ИИ-активов – это не бюрократия, а важный инструмент контроля в современных процессах разработки.
Что такое ИИ-актив и почему их сложно считать
Начнём с терминологии. ИИ-актив – это любой артефакт в репозитории, который участвует в работе ИИ-системы.
Модель может лежать в объектном хранилище, адаптер в соседней папке, промпт в конфиге, MCP-сервер в JSON-файле клиентской конфигурации, а датасет вообще во внешнем сервисе. Собрать эту картину вручную – задача на недели, и она устареет в момент завершения.
Именно поэтому в INFERA AI.SafeCode появился MLSecOps-скан репозитория, который формирует реестр ИИ-активов.
Сканер выделяет несколько типов:
|
Актив |
Что это |
Типичный риск |
|
Модель |
Файлы весов или ссылка на них |
Код исполняется при загрузке, происхождение не подтверждено |
|
Адаптер |
Надстройка над моделью (LoRA), меняющая её поведение |
Подмена поведения, адаптер без своей базовой модели |
|
Датасет |
Данные для обучения или дообучения |
Персональные данные, учётные данные, отравление, лицензия |
|
Промпт |
Постоянная инструкция модели в файле |
Незаметная правка поведения |
|
Векторное хранилище |
База, откуда модель берёт документы для ответа |
Доступ без ключа |
|
Агент |
Программа, которая сама решает, какой инструмент вызвать |
Лишние полномочия, необратимые действия без подтверждения |
|
MCP-сервер |
Поставщик инструментов для агента |
Скрытые указания в описании, версия не закреплена |
|
ML-библиотека |
Библиотека машинного обучения в зависимостях |
Известные уязвимости |
|
Провайдер |
Внешний ИИ-сервис, к которому обращается код |
Теневой ИИ |
|
Ноутбук |
Файл .ipynb с кодом и сохранёнными результатами |
Чувствительные значения в сохранённом выводе |
|
Пайплайн |
Шаг обучения или выкладки модели |
Доступ к сети, учётные данные, запись в каталог моделей |
Половина этих активов – конфигурации и данные, а не код, поэтому классический статический анализ их не видит.
Между активами есть связи: агент использует модель, получает инструменты от MCP-сервера и читает из векторного хранилища. Без связей реестр превращается в плоский список, по которому нельзя понять, что именно заденет дефект.
Каждый актив описывается одним и тем же набором атрибутов: имя и путь или адрес, тип, версия и дайджест, источник (внутренний реестр, HuggingFace, объектное хранилище, файл или узел, репозиторий, внешний сервис), статус подписи, лицензия, уровень риска и проект.
Реестр различает пять состояний:
|
Значение |
Как читать |
|
Подпись проверена |
Подпись есть и сошлась |
|
Только контрольная сумма |
Слепок файла совпал, криптографической подписи нет |
|
Нет подтверждения |
Ни подписи, ни контрольной суммы рядом не лежит |
|
Сумма не совпала |
Файл отличается от объявленного, разбираться нужно сразу |
|
Не проверялось |
Разбор артефактов до этого актива не дошёл |
Последняя строка принципиальна. «Не проверялось» не означает «подписи нет»: проверка просто не дотянулась до файла, например потому, что веса лежат вне репозитория. Если бы такие случаи показывались нулём, отчёт выглядел бы чище, чем есть на самом деле. Для ИБ это разница между «проверили, и всё в порядке» и «до этого не дошли», и она выписана словами, а не прячется в пустой ячейке.
Для запуска MLSecOps-скана нужен только репозиторий, сам скан детерминированный, читает код и конфигурации по правилам. Скан делает две вещи одновременно:
-
Наполняет реестр «ИИ-активы» – состав ИИ-системы.
-
Заводит находки – дефекты, которые попадают в общий раздел «Уязвимости» с типом MLSEC.
Еще раз отметим, что веса модели, лежащие в стороннем хранилище, платформа не скачивает. То, до чего она не дотянулась, помечается словами «не проверялось».
После завершения скана реестр наполняется, счётчики пересчитываются, а в карточках активов появляются записи журнала. Отмечается риск: критический, высокий, средний, низкий, справочно.
Карточка актива: всё об одном артефакте
Сканер собирает всё, что платформа знает об активе:
-
Свойства: тип, версия, источник, адрес, дайджест, подпись, лицензия, лицензионный риск, откуда лицензия, проект, впервые найден, последний раз найден.
-
Специфичные строки для отдельных типов: у промпта – длина и слепок текста (по нему следующий скан увидит, что инструкцию модели поменяли); у ноутбука – ячеек с кодом / всего, ячеек с сохранённым выводом, разбор (полный / частичный / не выполнялся); у датасета – формат набора, строк в наборе, просмотрено (сколько строк и какая это доля), колонки, найдено в выборке.
-
Где объявлен: список файлов и строк, в которых актив упоминается.
-
Как развёрнут: карточки сервисов из файлов развёртывания: имя, файл и строка, образ, порты наружу и цветные метки замечаний (аутентификация выключена, аутентификация не объявлена, доверие коду модели, CORS открыт всем, секрет в конфигурации, запись в каталог моделей).
-
Журнал изменений: что появилось в реестре, какая версия, изменились ли дайджест, источник, подпись, лицензия, риск.
-
Связи и с чем этот актив связан: использует модель, использует датасет, предоставляет, берёт инструменты у, читает из.
Какие дефекты ищет MLSecOps-скан
MLSecOps-скан смотрит на то, что вокруг модели. Разберём по категориям.
Агенты и MCP-серверы
Главный вопрос: что модель может сделать руками агента. Скан проверяет:
-
может ли инструмент выполнять команды оболочки;
-
выполняется ли необратимое действие без подтверждения человека;
-
не ослаблены ли разрешения агента;
-
ходит ли инструмент по произвольному адресу;
-
нет ли в описании инструмента скрытых указаний модели (отравленные описания);
-
закреплена ли версия MCP-сервера;
-
есть ли у агента перечень разрешённых инструментов;
-
не записаны ли учётные данные в описании сервера;
-
не изменилось ли описание инструмента с прошлого скана.
На вкладке «Агенты и MCP» видны четыре счётчика: хосты, инструменты, с правом выполнения, без подтверждения.
Инференс и векторные хранилища
Скан проверяет:
-
опубликован ли эндпоинт модели без аутентификации;
-
запускается ли сервис с доверием к коду из репозитория модели;
-
принимает ли он запросы с любого источника;
-
доступна ли база документов без ключа.
MLOps-обвязка, ноутбуки и промпты
Скан проверяет:
-
открыты ли реестр моделей и оркестратор;
-
нет ли учётных данных в определении сервиса;
-
не смонтирован ли шаг пайплайна в каталог моделей с правом записи;
-
не осталось ли в сохранённом выводе .ipynb чувствительных значений;
-
не изменилась ли постоянная инструкция модели с прошлого скана.
Файлы модели
Блок «Артефакты моделей» отвечает на вопрос «что произойдёт, когда эти веса загрузят». Скан проверяет:
-
исполняет ли формат код при загрузке;
-
нет ли опасных импортов в pickle-потоке;
-
нет ли произвольного Python внутри графа модели;
-
совпадает ли слепок файла с объявленным;
-
подтверждено ли происхождение;
-
лежит ли адаптер рядом со своей базовой моделью.
Важно: файлы модели при разборе не запускаются. Платформа читает структуру файла, а не загружает веса. Поэтому проверка безопасна даже для заведомо вредоносного артефакта.
Обучающие данные и среда дообучения
Вкладка «Датасеты» появляется, только если наборы данных нашлись.
Скан проверяет:
-
нет ли в наборе персональных данных и учётных записей;
-
прочитана ли лицензия набора и не запрещает ли она обучение;
-
нет ли признаков отравления: дубли, повторяющаяся фраза, аномально длинные записи;
-
какая часть набора была просмотрена;
-
изолирован ли шаг дообучения от сети;
-
не заданы ли в нём учётные данные напрямую;
-
не пишет ли он прямо в каталог моделей.
Здесь снова работает принцип честности: наборы читаются выборкой – целиком терабайтный файл никто не разбирает, поэтому в таблице всегда есть колонка «Доля выборки».
ML-BOM: ведомость состава ИИ-системы
Отдельная ценность реестра – выгрузка ML-BOM в формате CycloneDX. Это тот же принцип, что у SBOM для зависимостей, только про модели, адаптеры и данные. Формат понимают сторонние инструменты, поэтому файл можно приложить к релизу или передать заказчику.
Также есть карточка ML-стек – ML-библиотеки проекта и уязвимости, которые нашёл в них SCA-скан INFERA AI.SafeCode. Это пересечение реестра с результатами SCA-скана: если SCA по проекту не запускался, уязвимости в карточке не появятся.
Преимущества подхода
Почему такой подход – через реестр, наполняемый сканом – работает лучше, чем ручная инвентаризация или разрозненные проверки?
-
Полнота без ручного труда. Реестр не заполняется руками. Скан находит всё, что есть в коде и конфигурациях: модели, адаптеры, датасеты, промпты, векторные хранилища, агентов, MCP-серверы, ML-библиотеки, внешние ИИ-сервисы, ноутбуки и пайплайны – с версией, источником, лицензией и признаком «об этом никто не объявлял».
-
Честность формулировок. Платформа везде разделяет «проверили, и всё в порядке» и «до этого проверка не дошла». Такая дисциплина формулировок критична для ИБ-команды: она не даёт ложного чувства безопасности.
-
Детерминированность. MLSecOps-скан читает код и конфигурации по правилам. Это значит: нет расходов на токены, нет зависимости от каталога AI-моделей, нет вариативности в результатах между запусками.
-
Безопасный разбор артефактов. Файлы модели не запускаются, так как платформа читает структуру, а не загружает веса. Проверка безопасна даже для заведомо вредоносного файла.
-
История изменений. Журнал фиксирует события: версия сменилась, дайджест изменился, подпись изменилась, лицензия изменилась, риск изменился. Слепок текста промпта позволяет увидеть, что инструкцию модели поменяли. Это не разовая проверка, а наблюдение во времени.
-
Теневой ИИ становится видимым. Фильтр «Только не объявленные» оставляет в таблице только активы, которые найдены в коде, но нигде не объявлены. Это прямой ответ на вопрос «что у нас появилось мимо процесса».
-
Единая очередь с обычными уязвимостями. Находки MLSEC проходят в INFERA AI.SafeCode тот же триаж, что и SAST/SCA/DAST. Не нужно строить отдельный процесс для ИИ-безопасности – она встраивается в существующий.
-
Стандартизированная выгрузка. ML-BOM в CycloneDX понимают сторонние инструменты, ведомость можно приложить к релизу или передать заказчику.
Автор: INFERA

