Kort gezegd: Een openbare .git-map ontstaat wanneer een website met git clone of git pull rechtstreeks in de webroot wordt uitgerold en de webserver verborgen mappen niet blokkeert. Dan is de volledige broncode inclusief versiegeschiedenis op te halen, met ook vroeger ingecheckte toegangsgegevens. Controleer uw domeinen met een eenvoudige aanroep, blokkeer de toegang meteen, zet de deployment om naar pakketten zonder .git en vervang toegangsgegevens uit de geschiedenis.
De broncode om mee te nemen
Git is het standaardhulpmiddel voor versiebeheer en voor kleine teams ligt het voor de hand daarmee ook uit te rollen: verbinden met de server, git pull, klaar. Dat werkt betrouwbaar en snel. Het heeft echter een bijwerking die vaak niemand opmerkt.
In de projectmap staat een verborgen map .git. Die bevat niet alleen de actuele stand, maar elk bestand in elke versie die ooit is ingecheckt, plus commitberichten, namen en e-mailadressen van de ontwikkelaars en verwijzingen naar servers. Staat deze map in de webroot en levert de webserver hem uit, dan kan iedereen hem ophalen.
Voor aanvallers is dat een geschenk. Met de broncode zijn zwakke plekken gericht op te sporen in plaats van van buitenaf te raden. En in de geschiedenis staan vaak dingen die allang verwijderd leken: een databasewachtwoord uit de beginperiode, een API-sleutel, een testbestand met klantgegevens.
Is uw .git-map openbaar? Zo controleert u het
De controle duurt seconden en wijzigt niets. Roep voor elk domein en subdomein een bestand op dat in elke Git-repository bestaat:
# Verwacht: 403 of 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
# Op de server: bestaan er .git-mappen onder de webroots?
find /var/www /srv/www -maxdepth 4 -type d -name ".git" 2>/dev/null
Status 200 betekent: de map is bereikbaar. Let ook op submappen. Soms staat de repository niet in de webroot zelf, maar in een plug-in- of themamap die afzonderlijk via Git wordt bijgehouden.
Controleer bovendien staging- en testomgevingen. Die worden vaker via Git bijgewerkt dan de productie en zijn vaak bereikbaar onder te raden subdomeinen.
Meteen: de toegang blokkeren
Totdat de deployment is omgezet, blokkeert een regel in de webserver de toegang tot mappen van het versiebeheer. Een algemene blokkade voor verborgen bestanden, zoals beschreven in Toegangsgegevens en .env-bestanden correct beveiligen, dekt dat mee af. Wie gericht alleen het versiebeheer wil blokkeren, gebruikt een engere regel:
location ~ /\.(git|svn|hg)(/|$) {
return 404;
}
RedirectMatch 404 /\.(git|svn|hg)(/|$)
Herhaal daarna de controle van hierboven, en wel met een echte aanroep van buitenaf: een geslaagde configuratietest zegt alleen dat de syntaxis klopt, niet dat de regel vóór andere regels voor statische bestanden grijpt. Bij panelen zoals Plesk of cPanel voert u de regel in bij de daarvoor bedoelde aanvullende directieven, zodat hij bij de volgende generatie van de configuratie niet verloren gaat.
Was de map bereikbaar, behandel dan alle toegangsgegevens die ooit in de repository stonden als bekend. Blokkeren alleen volstaat dan niet, de waarden moeten worden vervangen.
Blijvend: uitrollen zonder .git in de webroot
De blokkade is een beveiliging, geen oplossing. Blijvend hoort versiebeheer niet op de productieserver. Beproefde wegen, afhankelijk van uw omgeving:
| Werkwijze | Hoe het werkt | Geschikt voor |
|---|---|---|
| Buildpakket uit de CI | Pipeline bouwt een archief zonder .git, de server pakt het uit in een nieuwe releasemap |
Teams met CI/CD |
git archive |
maakt een archief van een stand zonder versiegegevens | kleine projecten zonder pipeline |
rsync met uitsluitingen |
draagt alleen de noodzakelijke bestanden over | klassieke servers |
| Containerimage | Code wordt tijdens de build in de image gekopieerd, .git via .dockerignore uitgesloten |
containerbedrijf |
Een releasemap per versie met een symbolische link naar de actuele stand heeft nog een voordeel: bij problemen kunt u meteen terugschakelen. Voor containeropstellingen beschrijft CI/CD: PHP-images automatisch opnieuw bouwen hoe builds reproduceerbaar worden. Daar moet ook worden gecontroleerd dat .git niet in de image terechtkomt.
# Voorbeeld: pakket van een stand zonder versiegegevens maken
git archive --format=tar.gz -o release.tar.gz HEAD
Andere projectbestanden die niet in de webroot horen
De .git-map is het bekendste voorbeeld, maar niet het enige. Wie hele projectmappen uitrolt, brengt nog meer bestanden in de webroot die daar niets te zoeken hebben:
- Mappen van ontwikkelomgevingen zoals
.ideaof.vscode, waarin extensies voor bestandsupload soms serveradressen en toegangsgegevens opslaan. composer.jsonencomposer.lock, die de exacte versies van alle bibliotheken verraden en zo het zoeken naar bekende kwetsbaarheden vergemakkelijken.- Configuraties voor tests, buildhulpmiddelen en pipelines, die interne hostnamen en processen prijsgeven.
- Resten van besturingssystemen zoals
.DS_Store, die bestandslijsten van hele mappen bevatten.
De oplossing is dezelfde als bij de .git-map: lever alleen uit wat openbaar moet zijn, idealiter via een eigen submap als webroot. Wie de deployment toch al naar pakketten omzet, legt meteen een lijst van uitgesloten bestanden vast en controleert die bij elk nieuw hulpmiddel in het project.
Was de map open: geschiedenis en logboeken controleren
Blijkt dat de .git-map bereikbaar was, ga dan in deze volgorde te werk:
- Toegang blokkeren en de controle herhalen.
- Geschiedenis doorzoeken op welke geheimen ooit zijn ingecheckt: configuratiebestanden,
.env, sleutels, databasedumps. - Toegangsgegevens vervangen, en wel alle die in stap 2 zijn gevonden, ook als ze vandaag niet meer in de code staan.
- Toegangslogboeken beoordelen of bestanden onder
/.git/met status 200 zijn opgehaald en vanaf welke adressen. Hoe dat gaat, toont Weblogboeken na een aanval beoordelen. - Broncode gericht controleren, want aanvallers kennen hem nu. Bekende zwakke plekken moeten voorrang krijgen.
- Gegevensbescherming uitzoeken, als persoonsgegevens in de geschiedenis stonden, bijvoorbeeld testexports. De beoordeling neemt uw functionaris voor gegevensbescherming op zich.
Hulpmiddelen om repositories op geheimen te doorzoeken horen daarna blijvend in de pipeline. OWASP adviseert zulke controles uitdrukkelijk, als hook vóór het inchecken en in de CI.
Hoe helpt PHP SOS concreet?
- Wij controleren al uw domeinen en subdomeinen op bereikbare mappen van het versiebeheer.
- Wij blokkeren de toegang meteen en zetten de deployment om naar pakketten zonder versiegegevens.
- Wij doorzoeken de geschiedenis op geheimen en begeleiden de vervanging van de getroffen toegangen.
- Wij beoordelen de toegangslogboeken en documenteren of en wanneer gegevens zijn opgehaald.
Deze maatregelen zijn onderdeel van onze serverhardening voor PHP-webservers.
Veelgestelde vragen
Hoe ontstaat een openbare .git-map?
Meestal door een deployment met git clone of git pull rechtstreeks in de webroot. De map .git met de volledige versiegeschiedenis staat dan naast index.php en zonder blokkade levert de webserver de bestanden uit.
Is het genoeg om de .git-map te verwijderen?
Voor de toekomst wel, voor het verleden niet. Als de map bereikbaar was, kan de inhoud al zijn gekopieerd. Toegangsgegevens die ooit in de repository stonden, moet u daarom vervangen.
Helpt het om toegangsgegevens achteraf uit de Git-geschiedenis te verwijderen?
Het voorkomt dat nieuwe kopieën ze bevatten. Wie de repository al heeft opgehaald, bezit de oude standen nog steeds. Beslissend is daarom de vervanging van de toegangsgegevens, niet alleen het herschrijven van de geschiedenis.
Geldt dit ook voor andere versiebeheersystemen?
Ja. Ook mappen zoals .svn of .hg bevatten projectgegevens en horen nooit bereikbaar te zijn in de webroot. Een algemene blokkade voor bestanden en mappen met een punt vooraan dekt al deze gevallen af.