Cizí Git repozitář je běžná součást práce. Open source projekt, kód od dodavatele, zadání pracovního pohovoru, nový projekt v týmu nebo repo, které vám někdo pošle s prosbou o kontrolu.
Naklonovat ho je normální. Z bezpečnostního hlediska je zajímavé hlavně to, co nad tím adresářem začne běžet potom.
Editor může načíst konfiguraci projektu. Package manager může při instalaci spustit skripty. Build a testy spouštějí další kód. Submoduly mohou stáhnout další repozitáře. Coding agentAI systém, který nedává jen odpovědi, ale může samostatně používat nástroje a provádět kroky. Více může několik těchto kroků provést automaticky. A pokud jste místo normálního clone dostali celý adresář včetně .git, může chování samotného Gitu ovlivnit i lokální konfigurace repozitáře.
Neznamená to, že každý cizí projekt potřebuje vlastní forenzní laboratoř. Dává ale smysl vědět, ve kterém okamžiku už projekt pouze nečtete, ale dovolujete mu něco spustit.
Otevřít projekt nemusí znamenat jen zobrazit zdrojáky
Moderní editor nebo IDE není pasivní textový prohlížeč. Nad otevřeným projektem může načítat jeho vlastní nastavení, spouštět tasky, připravovat debugger, inicializovat build systém nebo aktivovat další projektovou automatizaci.
Proto například VS Code používá pro neznámé projekty Workspace Trust a Restricted Mode. Dokud projektu nedůvěřujete, omezuje mimo jiné tasks, debugging a některá workspace nastavení. JetBrains IDE mají podobný Safe Mode, ve kterém lze zdrojáky prohlížet bez spuštění například Maven nebo Gradle importu a dalších projektových skriptů.
Pokud editor při otevření neznámého projektu nabízí volbu typu „Trust this project?“, není to jen právní dialog k odkliknutí. Rozhoduje se tím mimo jiné o tom, které funkce projektu se smějí automaticky aktivovat.
Pro první prohlídku cizího repozitáře je proto vhodné nechat podobný restricted nebo safe režim zapnutý, pokud ho používaný nástroj nabízí.
Instalace závislostí už může spouštět kód
Další hranice je příprava projektu ke spuštění.
U JavaScriptového projektu najdete v README běžně například:
npm install
npm run dev
npm install přitom není pouze stažení souborů do node_modules. npm během instalace standardně podporuje lifecycle skripty jako preinstall, install, postinstall nebo prepare. Ty jsou normální součástí ekosystému a řada legitimních balíčků je používá. Zároveň jde o programový kód spuštěný během instalace.
U cizího projektu se proto vyplatí před instalací podívat minimálně na package.json a na to, jaké skripty projekt definuje.
Při první kontrole lze npm spustit také s vypnutými skripty:
npm install --ignore-scripts
Tím npm při instalaci nespustí skripty z package.json. Není to sandboxIzolované prostředí, ve kterém lze spouštět kód s menším dopadem na zbytek systému. Více ani důkaz, že je projekt bezpečný. Explicitní npm run dev, npm test nebo jiný příkaz určený ke spuštění skriptu svůj cílový skript stále provede.
Má to ale praktické použití: lze oddělit samotnou instalaci závislostí od dalšího kódu, který se má během instalace automaticky spouštět.
Stejný princip platí i mimo npm. Maven, Gradle, Python packaging, Make, Cargo a další build nebo package systémy mají vlastní mechanismy, kterými mohou během setupu a buildu spouštět další programy. Konkrétní příkazy se liší, bezpečnostní otázka je stejná: co všechno se skutečně provede, když udělám krok popsaný jako instalace, build nebo test?
Škodlivý příkaz nemusí vypadat škodlivě
Tohle jsem si vyzkoušel na skutečném škodlivém repozitáři z falešné pracovní nabídky.
README obsahovalo normální instrukci:
npm run dev
Projekt po jejím spuštění skutečně nastartoval. Současně se ale aktivoval škodlivý kódŠkodlivý software, který může špehovat, krást data, poškozovat zařízení nebo převzít kontrolu. Více, který si zjistil adresu svého serveru, stáhl další část programu a začal se zapisovat do vývojářských nástrojů.
Podstatné nebylo, že by někde v návodu stálo run-malware. Útočník schoval škodlivé chování za krok, který člověk při kontrole frontendu udělá úplně normálně.
Celý ten případ jsem rozebral v článku Spustil jsem malware. Adresu svého serveru si našel v blockchainu.
Proto nestačí hledat jen příkazy, které na první pohled vypadají nebezpečně. Důležité je také to, co běžný příkaz spustí dál a jaké další soubory nebo data si za běhu načte.
Coding agent může stejný řetězec projít sám
Coding agentAI systém, který nedává jen odpovědi, ale může samostatně používat nástroje a provádět kroky. Více tenhle problém nevytváří, ale umí ho výrazně zrychlit.
Když agentAI systém, který nedává jen odpovědi, ale může samostatně používat nástroje a provádět kroky. Více dostane úkol typu „projdi tenhle projekt a vysvětli mi ho“, může zůstat u čtení souborů. U zadání „rozběhni projekt“, „oprav testy“, „najdi chybu“ nebo „ověř, že aplikace funguje“ už může být instalace závislostí, build nebo spuštění testů normální součástí řešení.
AgentAI systém, který nedává jen odpovědi, ale může samostatně používat nástroje a provádět kroky. Více tedy nemusí udělat nic proti zadání. Může přesně splnit požadovaný úkol a přitom spustit škodlivý instalační nebo build skript.
Proto je důležitější omezit prostředí, ve kterém agentAI systém, který nedává jen odpovědi, ale může samostatně používat nástroje a provádět kroky. Více pracuje, než spoléhat na to, že pokaždé správně pozná nebezpečný příkaz.
Například Claude Code odděluje permissions a sandboxIzolované prostředí, ve kterém lze spouštět kód s menším dopadem na zbytek systému. Více. Permissions určují, které nástroje smí agentAI systém, který nedává jen odpovědi, ale může samostatně používat nástroje a provádět kroky. Více použít. SandboxIzolované prostředí, ve kterém lze spouštět kód s menším dopadem na zbytek systému. Více pak na úrovni operačního systému omezuje filesystem a síť pro BashBěžný unixový shell používaný v Linuxu a na serverech. Více i pro procesy, které BashBěžný unixový shell používaný v Linuxu a na serverech. Více spustí. Omezení se tedy vztahuje také na npm, build skripty a další potomky spuštěných procesů.
SandboxIzolované prostředí, ve kterém lze spouštět kód s menším dopadem na zbytek systému. Více lze v Claude Code zapnout pomocí:
/sandbox
Pro skutečně nedůvěryhodný projekt dává smysl kombinovat sandboxIzolované prostředí, ve kterém lze spouštět kód s menším dopadem na zbytek systému. Více s omezením přístupu k citlivým souborům a síti. Samotné potvrzování jednotlivých příkazů není stejně silná ochrana. U dlouhé série běžně vypadajících operací navíc rychle vzniká approval fatigue a člověk začne potvrzení odklikávat automaticky.
Jeden repozitář může přivést další
Git submoduly umožňují, aby hlavní projekt odkazoval na další Git repozitáře. Jejich konfigurace je uložená v souboru .gitmodules, který je normální součástí repozitáře.
Proto je rozdíl mezi:
git clone https://example.com/project.git
a:
git clone --recurse-submodules https://example.com/project.git
Ve druhém případě Git rovnou začne řešit i další repozitáře uvedené v projektu.
U neznámého projektu není důvod stahovat submoduly automaticky dřív, než se podíváte, kam odkazují. Stačí nejdřív zkontrolovat .gitmodules a teprve potom je podle potřeby inicializovat.
Git má pro automaticky vyvolané síťové operace vlastní protocol policy. Některé protokoly jsou standardně povolené, nebezpečnější ext je zakázaný a další mohou mít politiku user, která rozlišuje mezi přímou akcí uživatele a automatickou operací vyvolanou například submodulem.
Tyto defaulty není potřeba kvůli běžné práci měnit. Naopak není dobrý nápad je globálně povolovat volněji jen proto, že nějaký konkrétní projekt jinak nefunguje, aniž by bylo jasné proč.
Cizí .git je jiný případ
Doteď jsme počítali s normálním vzdáleným repozitářem, který si sami naklonujete.
Jiná situace nastane, když vám někdo pošle celý pracovní adresář například jako ZIP, přes sdílený disk nebo synchronizovanou složku:
project/
├── src/
├── package.json
├── README.md
└── .git/
V takovém případě jste nedostali jen zdrojové soubory a Git historii. Dostali jste také cizí lokální Git metadataÚdaje o komunikaci nebo souboru, ne nutně samotný obsah. Například čas, odesílatel, příjemce nebo po... Více.
Tady je důležitý rozdíl proti běžnému git clone. Při vzdáleném clone se lokální .git/config původního repozitáře ani jeho hooks nekopírují. Git si na vašem stroji vytvoří nový .git adresář a vlastní lokální konfiguraci.
Pokud ale někdo předá celý adresář včetně .git, dostáváte i konfiguraci a hooks, které připravil on.
Oficiální dokumentace Gitu na to upozorňuje přímo: některé konfigurační volby a hooks mohou spouštět libovolné příkazy, a proto není bezpečné normálně pracovat s .git, který pochází z nedůvěryhodného zdroje.
Aktuální příklad: GitSpawn a core.fsmonitor
Konkrétní ukázkou je výzkum GitSpawn od Manifold Security.
Git podporuje nastavení core.fsmonitor, které mu pomáhá rychleji zjišťovat změny souborů. Hodnotou ale může být také externí program.
V lokálním .git/config tedy může být nastavení ve smyslu:
[core]
fsmonitor = <program>
Někteří coding agentiAI systém, který nedává jen odpovědi, ale může samostatně používat nástroje a provádět kroky. Více po otevření Git repozitáře automaticky zjišťovali jeho stav pomocí Git příkazů. Při operaci, která potřebovala obnovit index, Git použil nastavený fsmonitor a spustil cizí program.
Takže i normálně vypadající:
git status
mohlo skončit spuštěním programu definovaného v podstrčeném .git/config.
Pro tuhle konkrétní cestu lze při automatickém zjišťování stavu použít:
git -c core.fsmonitor=false status
Volba -c přepíše konfiguraci pro právě spouštěný Git příkaz. Hodnota core.fsmonitor z repozitáře se tedy pro tento příkaz nepoužije.
Globální:
git config --global core.fsmonitor false
není proti škodlivému repo-local nastavení spolehlivá ochrana. Lokální .git/config má vyšší prioritu než globální konfigurace a může ji přepsat.
git -c core.fsmonitor=false status zároveň není obecné zabezpečení Gitu. Řeší konkrétní cestu přes core.fsmonitor. Git konfigurace i hooks mají další možnosti, jak ovlivnit chování programu.
safe.directory není seznam důvěryhodných projektů
Git má ochranu proti repozitářům vlastněným jiným uživatelem.
Ve výchozím stavu odmítne pracovat s repozitářem, který patří někomu jinému, a nebude ani parsovat jeho lokální config nebo spouštět hooks. Konkrétní výjimky lze přidat pomocí safe.directory.
To je užitečné například na víceuživatelském systému.
Není to ale obecná ochrana proti škodlivému repozitáři. Když si sami rozbalíte ZIP připravený někým jiným, výsledné soubory typicky vlastní váš účet. Git tedy nemá podle ownershipu důvod takový adresář odmítnout.
A pokud Git zahlásí problém s „dubious ownership“, není vhodné ho automaticky řešit:
git config --global --add safe.directory '*'
Hodnota * kontrolu ownershipu globálně vypne. Lepší je zjistit, proč má konkrétní repo jiného vlastníka, a případnou výjimku nastavit jen tam, kde ji skutečně potřebujete.
Když cizí .git opravdu potřebujete
Někdy není k dispozici původní vzdálený repozitář a potřebujete zachovat historii, branche nebo další Git metadataÚdaje o komunikaci nebo souboru, ne nutně samotný obsah. Například čas, odesílatel, příjemce nebo po... Více z předaného adresáře.
Git v takové situaci doporučuje nevstupovat běžně do původního repozitáře, ale nejdřív z něj vytvořit čistou kopii:
git clone --no-local /cesta/k/puvodnimu-repu /cesta/k/nove-kopii
--no-local zabrání použití optimalizací lokálního clone a Git vytvoří nový repozitář prostřednictvím svého běžného transportního mechanismu. Výsledná kopie tak nepřebírá původní lokální config a hooks.
Ani to není absolutní sandboxIzolované prostředí, ve kterém lze spouštět kód s menším dopadem na zbytek systému. Více. Serverovou část clone obsluhuje git-upload-pack a samotná Git dokumentace upozorňuje, že i ten má vlastní attack surface. U skutečně nedůvěryhodného .git proto doporučuje spustit tuto část pod neprivilegovaným uživatelem nebo použít další izolaci.
Pokud historii vůbec nepotřebujete, je jednodušší původní .git nepoužívat.
Omezit lze i automatické hledání bare repozitářů
Git umí pracovat také s bare repositories, tedy repozitáři bez běžného working tree.
Pokud je ve svém workflow nepoužíváte, Git nabízí jedno užitečné hardening nastavení:
git config --global safe.bareRepository explicit
Git pak nebude automaticky pracovat s bare repozitářem, který pouze objeví uvnitř adresářové struktury. Musí mu být určený explicitně.
Git dokumentace tuto volbu doporučuje zvážit právě jako ochranu proti útokům, kdy naklonovaný projekt obsahuje další bare repository a následný Git příkaz ho automaticky najde.
Když projekt opravdu musíte spustit
Statická kontrola má svoje limity. Někdy potřebujete aplikaci skutečně spustit, reprodukovat chybu, pustit testy nebo sledovat její chování.
V tu chvíli už víte, že budete spouštět cizí kód. Nejdůležitější proto není další jednotlivá volba Gitu, ale prostředí, ve kterém ten kód poběží.
Běžný pracovní účet vývojáře může mít přístup k SSH klíčům, privátním repozitářům, Git a cloudovým tokenům, produkčním .env, uloženým přihlášením, dalším zdrojovým kódům nebo běžícím credential agentům.
Cizí projekt většinu z toho nepotřebuje.
U projektu, kterému nedůvěřujete, ale potřebujete ho spustit, dává smysl použít jednorázové nebo jinak omezené prostředí bez skutečných přístupových údajů a bez zbytečného přístupu k datům hostitele.
Podle rizika může jít o sandboxIzolované prostředí, ve kterém lze spouštět kód s menším dopadem na zbytek systému. Více, separátní uživatelský účet, development environment vytvořený právě pro tento účel nebo jednorázový virtuální systém.
Container může být součástí takového řešení, ale samotné „běží to v Dockeru“ ještě neznamená dobrou izolaci. Docker bind mounty mají ve výchozím stavu právo zapisovat do namountovaných souborů hostitele. Přístup k Docker daemonu je ještě silnější; Docker dokumentace výslovně upozorňuje, že možnost ovládat daemon poskytuje root-level oprávněníRozhodnutí, co smí přihlášený uživatel vidět nebo dělat. Více na hostitelském systému.
U nedůvěryhodného kódu bych proto do containeru nepředával Docker socket, celý domovský adresář, SSH agentAI systém, který nedává jen odpovědi, ale může samostatně používat nástroje a provádět kroky. Více ani adresáře s credentialsÚdaje, kterými se přihlašujete ke službě. Typicky jméno, e-mail, heslo, kód nebo bezpečnostní klíč. Více. Pokud projekt potřebuje hostitelský adresář pouze číst, je vhodnější read-only mount než zápis.
Stejně důležitá je síť. Pokud projekt ke své funkci nepotřebuje libovolný odchozí přístup, není důvod mu ho automaticky dávat.
Snapshot virtuálního systému je užitečný pro návrat disku do předchozího stavu. Není ale bezpečnostní hranice proti úniku datSituace, kdy se citlivá nebo neveřejná data dostanou k někomu, kdo k nim neměl mít přístup. Více. TokenTajný řetězec, kterým se aplikace prokazuje vůči API. Více, který už cizí program odeslal ven, rollback nevrátí.
Praktický bezpečnostní baseline
Žádné z následujících opatření samo o sobě nedělá cizí repozitář důvěryhodným. Jednotlivé kroky omezují různé cesty, kterými může projekt nebo nástroje kolem něj spouštět kód a získávat přístup k okolnímu systému.
| Situace | Co udělat / nastavit | Proč | Co to neřeší |
|---|---|---|---|
| První otevření cizího projektu | Použít Restricted / Safe Mode, pokud ho editor nebo IDE podporuje. | Omezí automatické tasks, buildy a projektovou konfiguraci před kontrolou. | Nechrání před kódem, který později sami spustíte. |
| První npm instalace | npm install --ignore-scripts |
Zabrání automatickému spuštění lifecycle skriptů během instalace. | Není to sandboxIzolované prostředí, ve kterém lze spouštět kód s menším dopadem na zbytek systému. Více. Explicitní npm run svůj cílový skript spustí. |
| Git submoduly | Nezačínat automaticky s --recurse-submodules; nejdřív zkontrolovat .gitmodules. |
Hlavní repo může odkazovat na další zdroje kódu. | Neříká nic o bezpečnosti samotného hlavního repozitáře. |
| Git protocol policy | Bez konkrétního důvodu neuvolňovat globálně protocol.*.allow. |
Git má bezpečnostní defaulty pro automaticky vyvolané transporty a submoduly. | Povolený HTTPS nebo SSH remote může stále obsahovat škodlivý kódŠkodlivý software, který může špehovat, krást data, poškozovat zařízení nebo převzít kontrolu. Více. |
| Repo s jiným vlastníkem | Nepoužívat globálně safe.directory=*. Povolit jen konkrétní adresář, pokud je to skutečně potřeba. |
Zachová ownership ochranu Gitu. | Nechrání před škodlivým repem, které už vlastní váš účet. |
| Bare repositories | git config --global safe.bareRepository explicit, pokud bare repositories běžně nepotřebujete. |
Omezí automatické objevení bare repozitáře vloženého do cizího projektu. | Neřeší normální working-tree repozitáře ani jiné execution paths. |
Cizí celý .git |
git clone --no-local /zdroj /nova-kopie |
Vytvoří nový .git místo běžné práce přímo nad cizím configem a hooks. |
git-upload-pack má vlastní attack surface; vysoce nedůvěryhodný zdroj patří do izolaceIzolované prostředí, ve kterém lze spouštět kód s menším dopadem na zbytek systému. Více. |
Automatický git status nad nedůvěryhodným .git |
git -c core.fsmonitor=false status |
Pro tento příkaz nepoužije podstrčený core.fsmonitor z repozitáře. |
Řeší pouze tuto konkrétní GitSpawn cestu. |
| Coding agentAI systém, který nedává jen odpovědi, ale může samostatně používat nástroje a provádět kroky. Více | Použít sandboxIzolované prostředí, ve kterém lze spouštět kód s menším dopadem na zbytek systému. Více a omezit filesystem i síť. U Claude Code například /sandbox. |
Omezení platí také pro procesy spuštěné agentem, například npm nebo build skripty. | SandboxIzolované prostředí, ve kterém lze spouštět kód s menším dopadem na zbytek systému. Více nenahrazuje správně nastavené permissions a kontrolu citlivých operací. |
| Spuštění skutečně nedůvěryhodného kódu | Jednorázové nebo omezené prostředí bez SSH klíčů, produkčních tokenů, cloud credentialsÚdaje, kterými se přihlašujete ke službě. Typicky jméno, e-mail, heslo, kód nebo bezpečnostní klíč. Více, hostitelského Docker socketu a dalších nepotřebných dat. | Omezuje dopad, pokud se škodlivý kódŠkodlivý software, který může špehovat, krást data, poškozovat zařízení nebo převzít kontrolu. Více skutečně spustí. | Nezabrání samotnému spuštění škodlivého programu. |
| Docker | Nepředávat nedůvěryhodnému containeru Docker socket; hostitelské mounty omezit a podle potřeby použít read-only. | Docker socket poskytuje velmi silná oprávněníRozhodnutí, co smí přihlášený uživatel vidět nebo dělat. Více a zapisovatelný bind mount umožňuje měnit hostitelské soubory. | Container sám o sobě není úplná bezpečnostní hranice. |
| Git a okolní tooling | Udržovat podporovanou aktuální verzi přes běžný update mechanismus používaného systému. | Git, package managery, editory i runtime mají vlastní bezpečnostní chyby. | Aktualizace nechrání před legitimní funkcí, kterou škodlivý projekt použije přesně podle návrhu. |
Kolik důvěry projekt skutečně potřebuje?
U cizího repozitáře není potřeba rozhodnout jednou provždy, jestli je „bezpečný“ nebo „nebezpečný“.
Praktičtější je rozhodovat postupně.
Pro přečtení zdrojových souborů nepotřebuje projekt přístup k SSH klíčům. Pro instalaci závislostí nemusí být nutné automaticky spustit všechny install skripty. Coding agentAI systém, který nedává jen odpovědi, ale může samostatně používat nástroje a provádět kroky. Více, který má vysvětlit architekturu, nemusí mít automaticky právo spouštět libovolný software. A projekt, který potřebujete opravdu rozběhnout, nemusí běžet pod stejným účtem a se stejnými credentialsÚdaje, kterými se přihlašujete ke službě. Typicky jméno, e-mail, heslo, kód nebo bezpečnostní klíč. Více jako vaše běžná práce.
Čím méně důvěry konkrétní krok potřebuje, tím méně jí má smysl projektu dávat.
Řešíte bezpečnost konkrétního vývojového prostředí, CI nebo coding agentů?
Pokud potřebujete posoudit konkrétní workflow, oprávněníRozhodnutí, co smí přihlášený uživatel vidět nebo dělat. Více nebo bezpečnostní návrh, můžeme ho projít v rámci Bezpečnostní konzultace. Cílem je dojít ke konkrétnímu doporučení pro vaše prostředí, ne vyrábět zbytečně široký audit.
Zdroje
- Git documentation – SECURITY: práce s nedůvěryhodným repozitářem, config, hooks a doporučení pro cizí
.git. - git-config documentation:
safe.directory,safe.bareRepository, protocol policy acore.fsmonitor. - git-clone documentation: lokální clone a
--no-local. - npm Scripts documentation: lifecycle skripty při instalaci.
- npm install documentation:
--ignore-scripts,allowScriptsastrict-allow-scripts. - Claude Code Security a Sandboxing: permissions, filesystem a network isolationIzolované prostředí, ve kterém lze spouštět kód s menším dopadem na zbytek systému. Více.
- VS Code Workspace Trust.
- JetBrains Project Security.
- Docker Engine security a Bind mounts.
- Manifold Security: GitSpawn.
