Kort sagt: En offentlig .git-mappe opstår, når et website udrulles med git clone eller git pull direkte i webroot, og webserveren ikke spærrer skjulte mapper. Så kan hele kildekoden inklusive versionshistorikken hentes, herunder tidligt indtjekkede adgangsdata. Kontrollér jeres domæner med et enkelt kald, spær adgangen med det samme, omstil deployment til pakker uden .git, og udskift adgangsdata fra historikken.
Kildekoden til at tage med
Git er standardværktøjet til versionsstyring, og for små teams er det nærliggende også at udrulle med det: Forbind til serveren, git pull, færdig. Det fungerer pålideligt og er hurtigt. Det har dog en bivirkning, som ofte ingen lægger mærke til.
I projektmappen ligger en skjult mappe .git. Den indeholder ikke kun den aktuelle version, men hver fil i hver version, der nogensinde er blevet tjekket ind, dertil commit-meddelelser, udvikleres navne og e-mailadresser og henvisninger til servere. Ligger denne mappe i webroot, og leverer webserveren den, kan enhver hente den.
For angribere er det en gave. Med kildekoden kan sårbarheder søges målrettet i stedet for at gættes udefra. Og i historikken findes ofte ting, der for længst syntes slettet: en databaseadgangskode fra begyndelsen, en API-nøgle, en testfil med kundedata.
Er jeres .git-mappe offentlig? Sådan kontrollerer I det
Kontrollen tager sekunder og ændrer intet. Kald for hvert domæne og subdomæne en fil, der findes i ethvert Git-repository:
# Forventet: 403 eller 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
# På serveren: Findes der .git-mapper under webroots?
find /var/www /srv/www -maxdepth 4 -type d -name ".git" 2>/dev/null
En status 200 betyder: Mappen kan nås. Vær også opmærksom på undermapper. Nogle gange ligger repositoryet ikke i selve webroot, men i en plugin- eller theme-mappe, som vedligeholdes separat med Git.
Kontrollér desuden staging- og testmiljøer. De opdateres oftere med Git end produktionen og kan ofte nås under subdomæner, der er lette at gætte.
Med det samme: Spær adgangen
Indtil deployment er omstillet, spærrer en regel i webserveren adgangen til versionsstyringsmapper. En generel spærring af skjulte filer, som beskrevet i Beskyt adgangsdata og .env-filer rigtigt, dækker det med. Den, der kun målrettet vil spærre versionsstyringen, bruger en snævrere regel:
location ~ /\.(git|svn|hg)(/|$) {
return 404;
}
RedirectMatch 404 /\.(git|svn|hg)(/|$)
Gentag derefter kontrollen ovenfra, og det med et rigtigt kald udefra: En vellykket konfigurationstest siger kun, at syntaksen er i orden, ikke at reglen virker før andre regler for statiske filer. Ved paneler som Plesk eller cPanel indfører I reglen i de dertil beregnede ekstra direktiver, så den ikke går tabt ved næste konfigurationsgenerering.
Kunne mappen nås, behandler I alle adgangsdata, der nogensinde har stået i repositoryet, som kendte. Spærring alene er så ikke nok, værdierne skal udskiftes.
Varigt: Udrul uden .git i webroot
Spærringen er en sikring, ikke en løsning. Varigt hører versionsstyringen ikke hjemme på produktionsserveren. Gennemprøvede veje, afhængigt af jeres miljø:
| Fremgangsmåde | Sådan fungerer den | Egnet til |
|---|---|---|
| Build-pakke fra CI | Pipeline bygger et arkiv uden .git, serveren pakker det ud i en ny release-mappe |
Teams med CI/CD |
git archive |
genererer et arkiv af en version uden versionsdata | små projekter uden pipeline |
rsync med udeladelser |
overfører kun de nødvendige filer | klassiske servere |
| Container-image | Koden kopieres ind i imaget ved build, .git udelukkes via .dockerignore |
containerdrift |
En release-mappe pr. version med et symbolsk link til den aktuelle version har en yderligere fordel: Ved problemer kan I straks skifte tilbage. Til container-opsætninger beskriver CI/CD: Byg PHP-images automatisk påny, hvordan builds bliver reproducerbare. Dér bør det også kontrolleres, at .git ikke havner i imaget.
# Eksempel: Generér pakke af en version uden versionsdata
git archive --format=tar.gz -o release.tar.gz HEAD
Yderligere projektfiler, der ikke hører hjemme i webroot
.git-mappen er det mest kendte eksempel, men ikke det eneste. Den, der udruller hele projektmapper, bringer yderligere filer ind i webroot, som ikke har noget at gøre dér:
- Mapper fra udviklingsmiljøer som
.ideaeller.vscode, hvori udvidelser til filupload undertiden gemmer serveradresser og adgangsdata. composer.jsonogcomposer.lock, som afslører de nøjagtige versioner af alle biblioteker og dermed letter søgningen efter kendte sårbarheder.- Konfigurationer til tests, build-værktøjer og pipelines, der afslører interne værtsnavne og forløb.
- Rester fra operativsystemer som
.DS_Store, der indeholder fillister over hele mapper.
Løsningen er den samme som ved .git-mappen: lever kun det, der skal være offentligt, ideelt set via en egen undermappe som webroot. Den, der alligevel omstiller deployment til pakker, fastlægger samtidig en liste over udelukkede filer og kontrollerer den ved hvert nyt værktøj i projektet.
Hvis mappen var åben: Kontrollér historik og logge
Viser det sig, at .git-mappen kunne nås, går I frem i denne rækkefølge:
- Spær adgangen og gentag kontrollen.
- Gennemsøg historikken for, hvilke hemmeligheder der nogensinde er blevet tjekket ind: konfigurationsfiler,
.env, nøgler, database-dumps. - Udskift adgangsdata, og det alle dem, der blev fundet i trin 2, også selv om de i dag ikke længere står i koden.
- Analysér adgangsloggene for, om filer under
/.git/blev hentet med status 200, og fra hvilke adresser. Hvordan det gøres, viser Analysér webserver-logs efter et angreb. - Kontrollér kildekoden målrettet, for angribere kender den nu. Kendte svagheder bør udbedres med forrang.
- Afklar databeskyttelse, hvis der lå personoplysninger i historikken, f.eks. testeksporter. Vurderingen overtager jeres databeskyttelsesrådgiver.
Værktøjer til søgning efter hemmeligheder i repositories hører derefter varigt hjemme i pipelinen. OWASP anbefaler udtrykkeligt sådanne kontroller, som hook før indtjekning og i CI.
Hvordan hjælper PHP SOS konkret?
- Vi kontrollerer alle jeres domæner og subdomæner for tilgængelige versionsstyringsmapper.
- Vi spærrer adgangen med det samme og omstiller deployment til pakker uden versionsdata.
- Vi gennemsøger historikken for hemmeligheder og ledsager udskiftningen af de berørte adgange.
- Vi analyserer adgangsloggene og dokumenterer, om og hvornår data blev hentet.
Disse foranstaltninger er en del af vores serverhærdning til PHP-webservere.
Ofte stillede spørgsmål
Hvordan opstår en offentlig .git-mappe?
Oftest gennem et deployment med git clone eller git pull direkte i webroot. Mappen .git med hele versionshistorikken ligger så ved siden af index.php, og uden spærring leverer webserveren dens filer.
Er det nok at slette .git-mappen?
For fremtiden ja, for fortiden nej. Hvis mappen kunne nås, kan indholdet allerede være kopieret. Adgangsdata, der på et tidspunkt stod i repositoryet, bør I derfor udskifte.
Hjælper det at fjerne adgangsdata fra Git-historikken bagefter?
Det forhindrer, at nye kopier indeholder dem. Den, der allerede har hentet repositoryet, har fortsat de gamle versioner. Afgørende er derfor udskiftningen af adgangsdata, ikke blot omskrivningen af historikken.
Berører det også andre versionsstyringssystemer?
Ja. Også mapper som .svn eller .hg indeholder projektdata og bør aldrig kunne nås i webroot. En generel spærring for filer og mapper med punktum først dækker alle disse tilfælde.