Trumpai: viešas .git aplankas atsiranda, kai svetainė paskleidžiama per git clone ar git pull tiesiai žiniatinklio šakniniame kataloge, o žiniatinklio serveris neužrakina paslėptų aplankų. Tada galima atsisiųsti visą šaltinio kodą su versijų istorija, įskaitant anksčiau įtrauktus prisijungimo duomenis. Savo domenus patikrinkite paprastu kreipiniu, nedelsiant užrakinkite prieigą, diegimą perjunkite į paketus be .git ir pakeiskite istorijoje buvusius prisijungimo duomenis.
Šaltinio kodas pasiimti su savimi
Git yra standartinis versijų valdymo įrankis, o mažoms komandoms natūralu juo ir diegti: prisijungti prie serverio, git pull, ir viskas. Tai veikia patikimai ir greitai. Tačiau tai turi šalutinį poveikį, kurio dažnai niekas nepastebi.
Projekto kataloge yra paslėptas aplankas .git. Jame yra ne tik dabartinė būsena, bet ir kiekvienas failas kiekviena versija, kuri kada nors buvo įtraukta, taip pat commit pranešimai, kūrėjų vardai ir el. pašto adresai bei nuorodos į serverius. Jei šis aplankas yra žiniatinklio šakniniame kataloge ir žiniatinklio serveris jį pateikia, jį gali atsisiųsti kiekvienas.
Užpuolikams tai dovana. Turint šaltinio kodą, spragas galima ieškoti tikslingai, užuot jas spėliojus iš išorės. O istorijoje dažnai randama dalykų, kurie atrodė seniai ištrinti: duomenų bazės slaptažodis iš pradžios laikų, API raktas, bandomasis failas su klientų duomenimis.
Ar jūsų .git aplankas viešas? Taip patikrinate
Patikra trunka sekundes ir nieko nekeičia. Kiekvienam domenui ir subdomenui kvieskite failą, kuris egzistuoja kiekvienoje Git saugykloje:
# Tikimasi: 403 arba 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
# Serveryje: ar yra .git aplankų žemiau žiniatinklio šakninių katalogų?
find /var/www /srv/www -maxdepth 4 -type d -name ".git" 2>/dev/null
Būsena 200 reiškia: aplankas pasiekiamas. Atkreipkite dėmesį ir į poaplankius. Kartais saugykla yra ne pačiame žiniatinklio šakniniame kataloge, o papildinio ar temos aplanke, kuris tvarkomas atskirai per Git.
Patikrinkite taip pat parengiamąsias (staging) ir bandomąsias aplinkas. Jos per Git atnaujinamos dažniau nei gamyba ir dažnai pasiekiamos atspėjamuose subdomenuose.
Nedelsiant: užrakinti prieigą
Kol diegimas neperjungtas, taisyklė žiniatinklio serveryje užrakina prieigą prie versijų valdymo aplankų. Bendras paslėptų failų užraktas, kaip aprašyta Prisijungimo duomenų ir .env failų teisinga apsauga, tai apima. Kas nori užrakinti tik versijų valdymą, naudoja siauresnę taisyklę:
location ~ /\.(git|svn|hg)(/|$) {
return 404;
}
RedirectMatch 404 /\.(git|svn|hg)(/|$)
Po to pakartokite aukščiau pateiktą patikrą, ir būtent tikru kreipiniu iš išorės: sėkmingas konfigūracijos testas sako tik tai, kad sintaksė teisinga, o ne kad taisyklė suveikia anksčiau už kitas statinių failų taisykles. Su valdymo skydeliais kaip Plesk ar cPanel taisyklę įrašykite į tam numatytas papildomas direktyvas, kad ji nepradingtų kitą kartą generuojant konfigūraciją.
Jei aplankas buvo pasiekiamas, visus prisijungimo duomenis, kurie kada nors buvo saugykloje, laikykite žinomais. Vien užrakinti tada nepakanka, reikšmės turi būti pakeistos.
Ilgalaikis sprendimas: diegti be .git žiniatinklio šakniniame kataloge
Užraktas yra apsauga, o ne sprendimas. Ilgam versijų valdymui gamybos serveryje vietos nėra. Patikrinti keliai, priklausomai nuo jūsų aplinkos:
| Metodas | Kaip veikia | Tinka |
|---|---|---|
| Kūrimo (build) paketas iš CI | konvejeris sukuria archyvą be .git, serveris jį išpakuoja į naują leidimo katalogą |
komandoms su CI/CD |
git archive |
sukuria būsenos archyvą be versijų duomenų | maži projektai be konvejerio |
rsync su išimtimis |
perduoda tik reikalingus failus | klasikiniai serveriai |
| Konteinerio atvaizdas (image) | kodas kuriant nukopijuojamas į atvaizdą, .git išskirtas per .dockerignore |
konteinerių eksploatavimas |
Leidimo katalogas kiekvienai versijai su simboline nuoroda į dabartinę būseną turi dar vieną pranašumą: kilus problemoms galite nedelsiant grįžti atgal. Konteinerių sistemoms CI/CD: PHP atvaizdų automatinis perkūrimas aprašo, kaip kūrimai tampa atkuriami. Ten taip pat turėtų būti tikrinama, kad .git nepatektų į atvaizdą.
# Pavyzdys: sukurti būsenos paketą be versijų duomenų
git archive --format=tar.gz -o release.tar.gz HEAD
Kiti projekto failai, kurie nepriklauso žiniatinklio šakniniam katalogui
Aplankas .git yra žinomiausias pavyzdys, bet ne vienintelis. Kas diegia ištisus projektų katalogus, į žiniatinklio šakninį katalogą atneša ir kitų failų, kuriems ten ne vieta:
- Kūrimo aplinkų aplankai kaip
.ideaar.vscode, kuriuose failų įkėlimo plėtiniai kartais saugo serverių adresus ir prisijungimo duomenis. composer.jsonircomposer.lock, išduodantys tikslias visų bibliotekų versijas ir taip palengvinantys žinomų spragų paiešką.- Bandymų, kūrimo įrankių ir konvejerių konfigūracijos, atskleidžiančios vidinius pagrindinių kompiuterių vardus ir eigas.
- Operacinių sistemų likučiai kaip
.DS_Store, turintys ištisų katalogų failų sąrašus.
Sprendimas tas pats kaip su .git aplanku: pateikti tik tai, kas turi būti viešas, geriausia per atskirą poaplankį kaip žiniatinklio šakninį katalogą. Kas diegimą vis tiek perjungia į paketus, tuo pat metu nustato išskirtų failų sąrašą ir tikrina jį su kiekvienu nauju projekto įrankiu.
Jei aplankas buvo atviras: patikrinti istoriją ir žurnalus
Jei paaiškėja, kad .git aplankas buvo pasiekiamas, elkitės tokia tvarka:
- Užrakinti prieigą ir pakartoti patikrą.
- Peržiūrėti istoriją, kokios paslaptys kada nors buvo įtrauktos: konfigūracijos failai,
.env, raktai, duomenų bazių išklotinės (dump). - Pakeisti prisijungimo duomenis, ir būtent visus, rastus 2 žingsnyje, net jei šiandien jų kode nebėra.
- Įvertinti prieigos žurnalus, ar failai po
/.git/buvo kviečiami su būsena 200 ir iš kokių adresų. Kaip tai padaryti, rodo Žiniatinklio serverio žurnalų vertinimas po atakos. - Tikslingai patikrinti šaltinio kodą, nes užpuolikai dabar jį žino. Žinomos silpnybės turėtų būti šalinamos prioritetiškai.
- Išsiaiškinti duomenų apsaugą, jei istorijoje buvo asmens duomenų, pavyzdžiui, bandomųjų eksportų. Vertinimą perima jūsų duomenų apsaugos pareigūnas.
Paslapčių paieškos saugyklose įrankiai po to turi nuolat priklausyti konvejeriui. OWASP tokias patikras aiškiai rekomenduoja, kaip kabliuką (hook) prieš įtraukiant ir CI.
Kaip PHP SOS padeda konkrečiai?
- Tikriname visus jūsų domenus ir subdomenus dėl pasiekiamų versijų valdymo aplankų.
- Prieigą užrakiname nedelsiant ir diegimą perjungiame į paketus be versijų duomenų.
- Istorijoje ieškome paslapčių ir lydime paveiktų prieigų pakeitimą.
- Įvertiname prieigos žurnalus ir dokumentuojame, ar ir kada duomenys buvo kviečiami.
Šios priemonės yra mūsų PHP žiniatinklio serverių sutvirtinimo dalis.
Dažni klausimai
Kaip atsiranda viešas .git aplankas?
Dažniausiai dėl diegimo per git clone ar git pull tiesiai žiniatinklio šakniniame kataloge. Aplankas .git su visa versijų istorija tada guli šalia index.php, o be užrakto žiniatinklio serveris pateikia jo failus.
Ar pakanka ištrinti .git aplanką?
Ateičiai taip, praeičiai ne. Jei aplankas buvo pasiekiamas, turinys jau galėjo būti nukopijuotas. Prisijungimo duomenis, kurie kada nors buvo saugykloje, todėl turėtumėte pakeisti.
Ar padeda vėliau pašalinti prisijungimo duomenis iš Git istorijos?
Tai užkerta kelią, kad naujos kopijos juos turėtų. Kas saugyklą jau gavo, senas būsenas vis dar turi. Todėl lemia prisijungimo duomenų pakeitimas, o ne vien istorijos perrašymas.
Ar tai liečia ir kitas versijų valdymo sistemas?
Taip. Ir aplankuose kaip .svn ar .hg yra projekto duomenų, ir jie niekada neturi būti pasiekiami žiniatinklio šakniniame kataloge. Bendras užraktas failams ir aplankams su tašku pradžioje apima visus šiuos atvejus.