Hoe deze controle werkt
Scanaris vraagt negen bestandsnamen op die mensen keer op keer gebruiken om back-ups in de root van de site te bewaren: backup.zip, backup.tar.gz, website.zip, www.zip, public_html.zip, site.zip, database.sql, dump.sql en db.sql. Voor elk controleert hij dat het antwoord een echt bestand is en niet de generieke pagina van je site: hij kijkt naar het contenttype en, bij SQL-dumps, of de tekst op SQL lijkt. Alle bevindingen hebben kritieke ernst, omdat zo'n bestand ofwel de volledige code van de site bevat, ofwel de hele database.
Waarom dit belangrijk is
Een bereikbare backup.zip is je complete project: code, configuratie, de sleutels die in de bestanden rondslingerden en vaak een kopie van de database erbij. Een dump.sql is de database zoals hij is: gebruikers, e-mails, gehashte wachtwoorden (op het gemak te kraken), bestellingen, berichten. Geen techniek nodig: het is een download. En automatische scanners proberen precies deze namen tegen elk domein dat ze vinden, dus "niemand kent de URL" is geen bescherming.
Waarom het gebeurt
Uit gemak op het verkeerde moment: voor een migratie of update wordt de sitemap "voor de zekerheid" ingepakt en daar gelaten. Of een back-upplugin schrijft naar een openbare map. Of een databaseexport wordt naast de code opgeslagen om aan iemand door te geven. Op een server die de projectroot serveert, is elk bestand dat daar belandt meteen openbaar.
Hoe je het oplost
- Verwijder het bestand nu en handel alsof het is gedownload: roteer alle sleutels en wachtwoorden die erin stonden en, als er persoonsgegevens in zaten, beoordeel de meldplicht.
- Verplaats back-ups uit de openbare map. Back-ups horen in aparte opslag (een privé-bucket, een andere server), nooit in een map die de webserver serveert.
- Configureer de back-uptool zodat hij buiten de webroot schrijft. WordPress-plugins laten meestal toe de map te kiezen of naar een externe dienst te sturen.
- Blokkeer de extensies aan serverkant als tweede barrière. In nginx:
location ~* \.(zip|tar|gz|sql|bak)$ { deny all; }. In Apache een vergelijkbareFilesMatchmetRequire all denied. Bied je legitiem gecomprimeerde downloads aan, beperk ze dan tot een specifieke map. - Controleer de toegangslogs op 200-verzoeken naar deze namen: die vertellen je of er al iemand langs is geweest.
Controleer of het opgelost is
for p in backup.zip backup.tar.gz website.zip www.zip public_html.zip site.zip database.sql dump.sql db.sql; do
printf "%-18s " "$p"; curl -s -o /dev/null -w "%{http_code} %{content_type}\n" "https://jouwdomein.nl/$p"
done
Verwacht: 404 of 403. Een 200 in text/html bij een single-page app is haar generieke HTML; een 200 in application/zip, application/octet-stream of text/plain is het echte bestand.
Veelgestelde vragen
Mijn back-up heeft een naam die niemand zou raden.
Aanvalstools proberen duizenden namen en combinaties met het domein, de datum en woorden als "old" of "bak". Een ongewone naam verkleint het risico maar neemt het niet weg; de oplossing is dat het bestand niet in een openbare map staat.
En als het bestand met een wachtwoord is beveiligd?
Een ZIP met wachtwoord is net zo goed te downloaden en zonder limiet op pogingen te kraken op de computer van de aanvaller. Het blijft een kritieke bevinding.
De controle kijkt alleen in de root. En submappen?
Klopt, deze negen namen worden in de root getest. Open mapoverzichten, die een andere controle meet, zijn de gebruikelijke manier om back-ups in submappen te vinden; die sluiten en de extensies blokkeren dekt de rest.