FlawOpen

flawopen.com/AI Security/plugin4shell-ai-agent-plugin-sha-pin-bypass

● CWE-345 · Высокий
Исследования · FlawOpen

Plugin4Shell: обход SHA-пина плагина

Четыре установщика плагинов ИИ-агентов не проверяли commit после фиксации ревизии Git. Plugin4Shell выявил проблему; проверяйте итоговый SHA.[1]

💡 Простыми словами (ELI5)

Библиотека резервирует конкретное издание книги по уникальному каталожному номеру. Сотрудник запрашивает этот номер, но выдаёт другую книгу, если на полке есть ярлык с таким же текстом. SHA-пин — это каталожный номер; установщик должен проверить реально выбранный commit, прежде чем доверять плагину или запускать его.[1]

Ключевые понятия и термины

Commit SHA
Хеш, идентифицирующий конкретный объект commit в Git. Безопасная фиксация версии должна сравнивать разрешённый checkout с этим значением.[1], [2]
Неоднозначность Git ref
Git принимает идентификаторы объектов и имена веток как выражения ревизий. В некоторых условиях имя, похожее на идентификатор commit, может разрешиться как ref.[1]
Маркетплейс плагинов
Каталог, распространяющий расширения агентов и способный хранить проверенную ревизию. Клиент-установщик всё равно должен обеспечить соблюдение пина.[1]
CWE-345
Недостаточная проверка подлинности данных: система использует данные, не удостоверившись должным образом, что они соответствуют ожидаемому подлинному значению.[5]

Связи со стандартами

  • Ссылка CWE для слабого места, описанного в этом руководстве: CWE-345

Пошаговый сценарий атаки

Шаг 1

Маркетплейс фиксирует проверенный commit

Запись плагина указывает на репозиторий и конкретную SHA commit, которую должен использовать установщик.[1]

Шаг 2

Владелец репозитория может менять refs

По данным AIR Security, на хостах, разрешающих такие имена, контролирующий репозиторий может создать ветку по умолчанию с именем запрошенной SHA. Для Gemini CLI отдельно описан путь разрешения ref FETCH_HEAD.[1]

Шаг 3

Установщик делает checkout без проверки HEAD

До исправления Codex передавал запрошенную SHA в <code>git checkout</code> и считал успешное выполнение Git доказательством соблюдения пина.[1], [2]

Шаг 4

Клиент принимает или отклоняет полученное дерево

Исправление Codex считывает <code>git rev-parse HEAD</code> после checkout и прерывает работу при несовпадении. Без такой проверки подменённый код плагина может установиться и выполняться с правами пользователя агента.[2], [1]

Исходный код: Уязвимый vs Защищённый вариант

Уязвимый путь принимал успешное разрешение имени за подтверждение идентичности объекта. Патч сравнивает итоговый HEAD с пином маркетплейса и отказывается материализовать другой commit. Этот пример отражает исправление Codex; у остальных продуктов другие установщики, поэтому их исправления нельзя считать такими же.[2], [6]

УЯЗВИМАЯ РЕАЛИЗАЦИЯ
// До исправления из PR #34644 OpenAI Codex
if let Some(target) = sha.or(ref_name) {
    run_git(&["checkout", target], Some(destination))?;
}
// Успешный checkout считался доказательством соответствия SHA.
БЕЗОПАСНЫЙ ИСПРАВЛЕННЫЙ ВАРИАНТ
// Исправление Codex: проверяем разрешённый commit, а не только запрошенный аргумент
if let Some(sha) = sha {
    run_git(&["checkout", sha], Some(destination))?;
    let checked_out_sha =
        run_git_output(&["rev-parse", "HEAD"], Some(destination))?;
    if !checked_out_sha.eq_ignore_ascii_case(sha) {
        return Err(format!(
            "checked out Git SHA {checked_out_sha} does not match requested SHA {sha}"
        ));
    }
} else if let Some(ref_name) = ref_name {
    run_git(&["checkout", ref_name], Some(destination))?;
}

Чек-лист по защите системы для инженеров

Источники

← AI Security Directory →