flawopen.com/AI Security/plugin4shell-ai-agent-plugin-sha-pin-bypass
Plugin4Shell: обход SHA-пина плагина
Четыре установщика плагинов ИИ-агентов не проверяли commit после фиксации ревизии Git. Plugin4Shell выявил проблему; проверяйте итоговый SHA.[1]
Библиотека резервирует конкретное издание книги по уникальному каталожному номеру. Сотрудник запрашивает этот номер, но выдаёт другую книгу, если на полке есть ярлык с таким же текстом. SHA-пин — это каталожный номер; установщик должен проверить реально выбранный commit, прежде чем доверять плагину или запускать его.[1]
Ключевые понятия и термины
Commit SHA- Хеш, идентифицирующий конкретный объект commit в Git. Безопасная фиксация версии должна сравнивать разрешённый checkout с этим значением.[1], [2]
Неоднозначность Git ref- Git принимает идентификаторы объектов и имена веток как выражения ревизий. В некоторых условиях имя, похожее на идентификатор commit, может разрешиться как ref.[1]
Маркетплейс плагинов- Каталог, распространяющий расширения агентов и способный хранить проверенную ревизию. Клиент-установщик всё равно должен обеспечить соблюдение пина.[1]
CWE-345- Недостаточная проверка подлинности данных: система использует данные, не удостоверившись должным образом, что они соответствуют ожидаемому подлинному значению.[5]
Связи со стандартами
- Ссылка CWE для слабого места, описанного в этом руководстве: CWE-345
Пошаговый сценарий атаки
Маркетплейс фиксирует проверенный commit
Запись плагина указывает на репозиторий и конкретную SHA commit, которую должен использовать установщик.[1]
Владелец репозитория может менять refs
По данным AIR Security, на хостах, разрешающих такие имена, контролирующий репозиторий может создать ветку по умолчанию с именем запрошенной SHA. Для Gemini CLI отдельно описан путь разрешения ref FETCH_HEAD.[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))?;
}
Чек-лист по защите системы для инженеров
- ✓После каждого checkout, закреплённого SHA, разрешайте фактически выбранный commit (например, через <code>git rev-parse HEAD</code>) и точно сравнивайте его с запрошенным пином до загрузки файлов плагина.[2], [6]
- ✓Рекомендация FlawOpen по реализации: Прерывайте установку при несовпадении, отсутствии HEAD, ошибке команды или неожиданном формате ревизии; не переходите на имя ветки как запасной вариант.[2]
- ✓Проверяйте установщик на временном локальном репозитории, где имя ветки по умолчанию совпадает с SHA другого commit; материализация должна отклоняться, а код плагина не должен загружаться.[6]
- ✓Рекомендация FlawOpen по реализации: Разделяйте имена refs и неизменяемые SHA-пины в типах и логике; записывайте проверенный commit в метаданные установки.[1]
- ✓Составьте перечень версий агентов и Git-хостов маркетплейсов. GitHub запрещает SHA-подобные имена веток, но это правило не защищает другие поддерживаемые хосты и описанный для Gemini путь FETCH_HEAD.[1], [4]
- ✓В цитируемом раскрытии AIR указано, что исправления вошли в Codex 0.146.0 и Claude Code 2.1.179, но полные диапазоны уязвимых версий не приведены. Перед рекомендациями по Copilot и Gemini CLI проверьте актуальные указания поставщиков.[1], [3], [7]
- ✓Сохраните регрессионный тест Codex
materialize_git_source_rejects_sha_that_resolves_to_hostile_default_branch: он создаёт временный локальный репозиторий и проверяет, что несовпадающий HEAD отклоняется до материализации исходников плагина.[6]
Источники
- AIR Security: раскрытие Plugin4Shell и согласованный статус поставщиков
- PR OpenAI Codex #34644: проверка Git checkout плагина по SHA
- Релиз OpenAI Codex 0.146.0
- The Hacker News: независимый материал и ограничения отдельных Git-хостов
- MITRE CWE-345: недостаточная проверка подлинности данных
- Codex regression test: reject SHA resolving to hostile default branch
- Релиз Anthropic Claude Code 2.1.179