Stručne: Verejný priečinok .git vzniká, keď sa web nasadí cez git clone alebo git pull priamo do webového koreňa a webserver neblokuje skryté priečinky. Potom sa dá stiahnuť celý zdrojový kód aj s históriou verzií, vrátane skôr commitnutých prístupových údajov. Svoje domény skontrolujte jednoduchým volaním, prístup okamžite zablokujte, nasadzovanie prestavte na balíky bez .git a prístupové údaje z histórie vymeňte.
Zdrojový kód so sebou
Git je štandardný nástroj na správu verzií a pre malé tímy je prirodzené nasadzovať ním aj na server: pripojiť sa na server, git pull, hotovo. Funguje to spoľahlivo a rýchlo. Má to však vedľajší účinok, ktorého si často nikto nevšimne.
V priečinku projektu leží skrytý priečinok .git. Neobsahuje len aktuálny stav, ale každý súbor v každej verzii, ktorá bola kedy commitnutá, k tomu správy commitov, mená a e-mailové adresy vývojárov a odkazy na servery. Ak tento priečinok leží vo webovom koreni a webserver ho doručuje, môže si ho stiahnuť ktokoľvek.
Pre útočníkov je to darček. So zdrojovým kódom sa dajú zraniteľnosti hľadať cielene, namiesto toho, aby sa hádali zvonka. A v histórii sa často nájdu veci, ktoré sa zdali dávno zmazané: databázové heslo z úplných začiatkov, kľúč API, testovací súbor s údajmi zákazníkov.
Je váš priečinok .git verejný? Takto to skontrolujete
Kontrola trvá sekundy a nič nemení. Pre každú doménu a subdoménu zavolajte súbor, ktorý existuje v každom repozitári Git:
# Očakáva sa: 403 alebo 404
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.git/HEAD
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.git/config
# Na serveri: existujú priečinky .git pod webovými koreňmi?
find /var/www /srv/www -maxdepth 4 -type d -name ".git" 2>/dev/null
Stav 200 znamená: priečinok je dostupný. Dávajte pozor aj na podpriečinky. Niekedy repozitár neleží priamo vo webovom koreni, ale v priečinku pluginu alebo témy, ktorý sa spravuje osobitne cez Git.
Skontrolujte aj staging a testovacie prostredia. Aktualizujú sa cez Git častejšie než produkcia a často sú dostupné na uhádnuteľných subdoménach.
Okamžite: zablokovať prístup
Kým nie je nasadzovanie prestavané, pravidlo vo webservery zablokuje prístup k priečinkom systému správy verzií. Všeobecné blokovanie skrytých súborov, ako je opísané v článku Správna ochrana prístupových údajov a súborov .env, to pokrýva tiež. Kto chce blokovať cielene len správu verzií, použije užšie pravidlo:
location ~ /\.(git|svn|hg)(/|$) {
return 404;
}
RedirectMatch 404 /\.(git|svn|hg)(/|$)
Potom kontrolu zhora zopakujte, a to skutočným volaním zvonka: úspešný test konfigurácie hovorí len to, že syntax je v poriadku, nie že pravidlo zaberie pred inými pravidlami pre statické súbory. Pri paneloch ako Plesk alebo cPanel pravidlo zapíšte do určených dodatočných direktív, aby sa pri ďalšom generovaní konfigurácie nestratilo.
Ak bol priečinok dostupný, všetky prístupové údaje, ktoré kedy v repozitári boli, považujte za známe. Samotné blokovanie vtedy nestačí, hodnoty sa musia vymeniť.
Natrvalo: nasadzovať bez .git vo webovom koreni
Blokovanie je zabezpečenie, nie riešenie. Natrvalo správa verzií na produkčný server nepatrí. Osvedčené cesty podľa vášho prostredia:
| Postup | Ako funguje | Vhodné pre |
|---|---|---|
| Balík buildu z CI | pipeline zostaví archív bez .git, server ho rozbalí do nového priečinka vydania |
tímy s CI/CD |
git archive |
vytvorí archív stavu bez údajov o verziách | malé projekty bez pipeline |
rsync s vylúčeniami |
prenáša len potrebné súbory | klasické servery |
| Obraz kontajnera | kód sa pri zostavení skopíruje do obrazu, .git sa vylúči cez .dockerignore |
prevádzka v kontajneroch |
Priečinok vydania pre každú verziu so symbolickým odkazom na aktuálny stav má ďalšiu výhodu: pri problémoch sa môžete okamžite vrátiť. Pre prostredia s kontajnermi opisuje CI/CD: automatické prestavovanie obrazov PHP, ako sa buildy stanú reprodukovateľnými. Tam by sa malo kontrolovať aj to, že .git nepreniká do obrazu.
# Príklad: vytvoriť balík stavu bez údajov o verziách
git archive --format=tar.gz -o release.tar.gz HEAD
Ďalšie súbory projektu, ktoré nepatria do webového koreňa
Priečinok .git je najznámejší príklad, ale nie jediný. Kto nasadzuje celé priečinky projektu, prináša do webového koreňa ďalšie súbory, ktoré tam nemajú čo robiť:
- Priečinky vývojových prostredí ako
.ideaalebo.vscode, v ktorých rozšírenia pre nahrávanie súborov niekedy ukladajú adresy serverov a prístupové údaje. composer.jsonacomposer.lock, ktoré prezrádzajú presné verzie všetkých knižníc, a tým uľahčujú hľadanie známych zraniteľností.- Konfigurácie pre testy, nástroje buildu a pipeline, ktoré odhaľujú interné názvy hostiteľov a postupy.
- Zvyšky operačných systémov ako
.DS_Store, ktoré obsahujú zoznamy súborov celých priečinkov.
Riešenie je rovnaké ako pri priečinku .git: doručovať len to, čo musí byť verejné, ideálne cez vlastný podpriečinok ako webový koreň. Kto tak či tak prestavuje nasadzovanie na balíky, určí pritom hneď zoznam vylúčených súborov a skontroluje ho pri každom novom nástroji v projekte.
Keď bol priečinok otvorený: skontrolovať históriu a protokoly
Ak sa ukáže, že priečinok .git bol dostupný, postupujte v tomto poradí:
- Zablokovať prístup a zopakovať kontrolu.
- Prehľadať históriu, aké tajomstvá boli kedy commitnuté: konfiguračné súbory,
.env, kľúče, výpisy databázy. - Vymeniť prístupové údaje, a to všetky, ktoré sa našli v kroku 2, aj keď už dnes v kóde nie sú.
- Vyhodnotiť prístupové protokoly, či sa súbory pod
/.git/sťahovali so stavom 200 a z akých adries. Ako na to, ukazuje Vyhodnotenie protokolov webservera po útoku. - Cielene skontrolovať zdrojový kód, pretože ho útočníci teraz poznajú. Známe slabiny by sa mali odstrániť prednostne.
- Vyjasniť ochranu údajov, ak v histórii boli osobné údaje, napríklad testovacie exporty. Posúdenie preberie váš zodpovedný pracovník pre ochranu údajov.
Nástroje na hľadanie tajomstiev v repozitároch potom patria natrvalo do pipeline. OWASP takéto kontroly výslovne odporúča, ako hook pred commitom a v CI.
Ako konkrétne pomáha PHP SOS?
- Skontrolujeme všetky vaše domény a subdomény na dostupné priečinky systému správy verzií.
- Okamžite zablokujeme prístup a prestavíme nasadzovanie na balíky bez údajov o verziách.
- Prehľadáme históriu na tajomstvá a sprevádzame výmenu dotknutých prístupov.
- Vyhodnotíme prístupové protokoly a zdokumentujeme, či a kedy sa údaje sťahovali.
Tieto opatrenia sú súčasťou nášho spevnenia servera (hardening) pre webservery PHP.
Časté otázky
Ako vzniká verejný priečinok .git?
Zvyčajne nasadzovaním cez git clone alebo git pull priamo vo webovom koreni. Priečinok .git s celou históriou verzií potom leží vedľa index.php a bez blokovania webserver jeho súbory doručuje.
Stačí priečinok .git zmazať?
Pre budúcnosť áno, pre minulosť nie. Ak bol priečinok dostupný, obsah mohol byť už skopírovaný. Prístupové údaje, ktoré niekedy v repozitári boli, by ste preto mali vymeniť.
Pomáha odstrániť prístupové údaje dodatočne z histórie Git?
Zabráni to tomu, aby ich obsahovali nové kópie. Kto už repozitár stiahol, má staré stavy naďalej. Rozhodujúca je preto výmena prístupových údajov, nielen prepísanie histórie.
Týka sa to aj iných systémov na správu verzií?
Áno. Aj priečinky ako .svn alebo .hg obsahujú údaje projektu a nikdy by nemali byť dostupné vo webovom koreni. Všeobecné blokovanie súborov a priečinkov s bodkou na začiatku pokrýva všetky tieto prípady.