Bezpečnostní firma Air Security popsala chybu, kterou ve stejné podobě udělaly čtyři největší laboratoře najednou: Claude Code, OpenAI Codex, GitHub Copilot i Gemini CLI si při instalaci pluginu stáhnou přesně tu verzi kódu, kterou marketplace schválil — ale už nikdy neověří, že v pracovním adresáři opravdu skončila. Zamknutí na konkrétní commit, celý smysl toho opatření, tím přestane platit. Reprodukoval jsem si obě varianty útoku lokálně a fungují přesně tak, jak je autoři popsali. Dobrá zpráva pro většinu českých firem je ale v detailu, který v přehledech obvykle chybí: rozhoduje, kde máte plugin uložený.
Co se stalo
- Kdo a kdy: Air Security zveřejnila 18. září 2026 rozbor Plugin4Shell. Podle jejich vlastní časové osy chybu našli v květnu 2026 s funkčním PoC proti všem čtyřem agentům a v červnu ji nahlásili výrobcům v rámci koordinovaného zveřejnění.
- Na čem to stojí: marketplace zamkne plugin na konkrétní commit (40místný hash). Agent udělá
git cloneagit checkout <hash>. Jenže když v repozitáři existuje větev pojmenovaná přesně jako ten hash a je nastavená jako výchozí, git dá přednost větvi před objektem. Vypíše jen varovánírefname is ambiguousa nainstaluje jiný kód. Agent přitom hlásí úspěšnou instalaci na zamčené verzi. - Proč je to bez kliknutí: tentýž
checkoutse pouští i při automatické aktualizaci pluginů na pozadí, která je podle Air v Claude Code a Codexu zapnutá ve výchozím stavu. Uživatel nemusí nic instalovat ani nic odklikávat — stačí, že plugin už dávno má. - Potvrzení od výrobce, ne od výzkumníka: OpenAI popisuje tutéž chybu ve svém veřejném pull requestu #34644: git „může požadovaný commit SHA interpretovat jako název větve, když výchozí větev vzdáleného repozitáře nese stejný název", což může způsobit, že se „zhmotní jiný commit, než který byl zamčen". Oprava je podle changelogu vydání 0.146.0 uvedená jako „Verify Git plugin SHA checkouts".
- Stav oprav podle Air: Anthropic opravil v Claude Code 2.1.179, OpenAI v Codexu 0.146.0. GitHub Copilot podle Air opravu nevydal. Gemini CLI Google opravovat nebude — nástroj ukončil a odkazuje uživatele na Antigravity.
Co jsem si ověřil sám (a co jsem přitom zjistil navíc)
Popis chyby se dá ověřit bez jakéhokoli agenta — stačí git. Postavil jsem si lokální repozitář s neškodným souborem, zapsal si jeho hash jako „schválený", pak obsah přepsal, vytvořil větev pojmenovanou tím hashem a nastavil ji jako výchozí. Klient poté udělal přesně to, co dělá agent:
git clone <repo> ./
git checkout 7144806e1debe2e79a41735a35bc94c029cbe56d
Git vypsal Already on '7144806e...' — tedy zprávu, která vypadá jako úspěch — ale v pracovním adresáři byl obsah z útočníkovy větve a git rev-parse HEAD vrátil úplně jiný commit než ten zamčený. Stejně dopadla i druhá varianta popsaná u Gemini CLI: repozitář, jehož výchozí větev se jmenuje FETCH_HEAD, přebije správně stažený commit a git checkout FETCH_HEAD nainstaluje obsah větve. Chyba tedy není v ničem exotickém, je to standardní chování gitu při kolizi jmen.
Při ověřování jsem ale narazil na tři věci, které v přehledech obvykle nezazní:
- Anthropic tu opravu ve svých poznámkách k vydání nezmiňuje. Prošel jsem release notes k verzi 2.1.179: je tam devět položek o padajících streamech, scrollování ve WSL2 a fokusu v panelu, o bezpečnostní opravě ani slovo. Že je chyba opravená právě tam, tvrdí jen Air. To není důvod tomu nevěřit, ale je dobré vědět, že si to podle poznámek k vydání neověříte.
- Žádné CVE, žádné bezpečnostní oznámení. Ke dni psaní není chybě přiděleno CVE a žádný ze čtyř výrobců k ní nevydal advisory. Jestli máte proces, který reaguje na CVE feed, tenhle nález vám jím neprojde.
- GitHub tenhle trik blokuje — a to mění, koho se to týká. V dokumentaci GitHubu stojí, že odmítá jména větví a tagů, která vypadají jako Git object ID (40 znaků 0–9 a A–F), právě aby nedošlo k záměně. Výchozí marketplace všech těch agentů běží na GitHubu.
Proč se to týká i vás
Většina firem, které tyhle agenty používají tak, jak přišly z krabice, tímhle konkrétním trikem ohrožená není — a je férové to říct nahlas, protože z titulku „zero-click RCE ve čtyřech agentech" to nevyplývá. Riziko se koncentruje tam, kde jste udělali krok navíc, který se obvykle považuje za ten zodpovědnější.
Dokumentace Claude Code výslovně uvádí jako podporované zdroje marketplace nejen GitHub, ale i „jakoukoli git URL, včetně GitLabu, Bitbucketu a self-hosted serverů". A přesně tohle dělá typická česká firma, která to myslí vážně: rozjede si vlastní interní marketplace pluginů na firemním GitLabu nebo Bitbucketu, protože nechce, aby vývojáři tahali doplňky z internetu. Na takovém serveru nic nebrání vytvořit větev pojmenovanou jako hash. Zamčení na commit, o které se ta interní kontrola opírá, tam tedy nedrží.
Druhá skupina jsou dodavatelé. Když vám externí vývojářský tým pracuje s agentem, který má přístup k vašemu repozitáři a přihlašovacím údajům, plugin běží s jeho oprávněními — tedy dosáhne na všechno, na co dosáhne ten člověk. To je stejný vzorec, na který jsem tu narazil už u agenta, který se přihlásil správným heslem: nic se neprolomilo, jen se zneužilo oprávnění, které tam legitimně bylo.
Z pohledu povinností to zapadá i do regulace. Komise v přehledu vymáhání AI Aktu řadí kontrolu dodavatelského řetězce mezi to, co se od firem čeká, a španělský ÚOOÚ ve svém blogu k prvnímu ohlášenému incidentu s AI agentem píše totéž jinými slovy: obecná zmínka o malwaru v analýze rizik nestačí, protože automatizace mění pravděpodobnost i rychlost incidentu.
Co s tím
- 1. Zjistěte verzi, ne značku. Spusťte
claude --versionacodex --versionna strojích vývojářů. Potřebujete Claude Code 2.1.179 nebo novější a Codex 0.146.0 nebo novější. U Copilotu podle Air oprava není, u Gemini CLI nebude nikdy — pokud ho někdo u vás používá s pluginy, je to položka k migraci, ne k čekání. - 2. Zjistěte, odkud vaše pluginy pocházejí. Tohle je ta podstatná otázka. Jestli všechny pluginy přicházejí z výchozích marketplaců na GitHubu, jste na branch trik krytí i bez aktualizace. Jestli máte vlastní marketplace na interním GitLabu, Bitbucketu nebo jiném hostingu, jste přesně v té skupině, na kterou to míří.
- 3. Na vlastním git serveru zakažte jména větví ve tvaru hashe. Je to jedno pravidlo pro příjem změn: odmítnout název větve nebo tagu odpovídající 40 znakům z rozsahu 0–9 a a–f, plus název
FETCH_HEAD. GitHub to dělá právě proto a je to obrana, kterou máte plně ve svých rukou — na rozdíl od opravy v agentovi. - 4. Sepište, co vlastně plugin smí. Plugin běží s oprávněními člověka, který agenta spustil. Napište si na jednu stránku, k jakým repozitářům, klíčům a systémům ten člověk má přístup — to je přesně rozsah škody. Většinou z toho vypadne, že vývojářský účet dosáhne na víc, než by pro tu práci potřeboval.
A teď proti vlastnímu byznysu: jestli vaši lidé používají Claude Code nebo Codex v aktuální verzi a pluginy berou jen z výchozích marketplaců, které běží na GitHubu, tenhle nález pro vás znamená nulu úkolů. Není to důvod objednávat si audit, není to důvod svolávat schůzku a rozhodně to není důvod agenty zakazovat. Jde o chybu v konkrétním kroku instalace, která má konkrétní opravu a která se vás při běžném nastavení netýká. Kdo vám na základě titulku „čtyři největší agenti mají zero-click RCE" nabídne bezpečnostní projekt, aniž se nejdřív zeptá, odkud berete pluginy, prodává vám strach, ne řešení.
Kde to řeším s klienty
Kde to naopak dává smysl probrat společně, je situace, kdy si firma staví vlastní interní katalog pluginů nebo skillů pro vývojářské týmy — tam je potřeba rozmyslet, kdo schvaluje, co se do něj dostane, a čím je to schválení vynucené, protože zamčení na commit samo o sobě nestačí. Tenhle rozbor je součástí AI Agent Governance Checkupu. Pokud nemáte přehled, kam až vaši agenti a jejich doplňky dosáhnou, začněte AI Risk Scanem zdarma. Na stejné téma jsem tu psal dřív: agent si vypnul vlastní sandbox jedním příkazem a do OpenAI se dostali dekodérem obrázků. Pokaždé selhal obyčejný krok v dodavatelském řetězci a teprve agent z něj udělal přístup tam, kam neměl.