Is a site serving its .git directory to the public?
A .git directory is the bookkeeping Git keeps beside a project: every version of every file, every commit message, and the remote it was cloned from. It ends up on the public web the moment a site is deployed by cloning into the document root rather than by copying a build, and from then on the whole repository can be downloaded by anyone who asks for the right path.
What an exposed repository costs
This is the worst outcome in the exposed-files group, and the reason is history. Blocking access does not undo it: a downloaded repository contains every commit ever made, so an API key that was committed in error and removed the next day is still sitting in that history, fully readable. The database password, the mail credentials, and the payment keys of past deployments are all in the same place.
The second cost is reconnaissance. Source code shows which framework and version run the site, where the admin routes live, and which validation happens only in the browser. Every later attack gets cheaper once an attacker can read the code instead of guessing at it.
Why a passive scan cannot answer this
Asking a server for /.git/HEAD means probing for a file that was never linked, and doing that to a domain without permission is the line between reading a site and testing it. CheckWeb keeps that line: the free passive scan reads only what a site shows every visitor, so it never checks this, and a clean passive report is not evidence that a .git directory is absent.
The check runs in the Deep Audit instead, after domain ownership is verified, alongside the rest of the exposed-files group: environment files, database dumps, editor backups of wp-config.php, and archive files left in the web root. Verification is what makes the probe legitimate, which is why it gates the whole active layer rather than being a plan feature.
How it looks in the report
In a Deep Audit this appears as a Critical finding titled "Git repository is publicly readable", with the path that answered and the signal that identified it, so the verdict can be confirmed by hand. A second finding, "Git configuration is publicly readable", fires on /.git/config, which names the remote and sometimes carries an access token directly in the URL.
Git repository is publicly readable
The .git directory is being served, so the full repository can be downloaded, history included.
/.git/HEAD
Exposed vs blocked
Exposed
A request for /.git/HEAD returns a Git ref instead of the site's 404 page. Everything else in the repository follows from that one answer.
Blocked
Requests for paths beginning with a dot are refused at the web server or the CDN, and the deployed directory holds a build artefact with no .git in it at all.
Blocking is the first step, not the whole fix: anything the history exposed stays exposed until it is rotated.
How to fix it
- Nginx: deny the path outright with `location ~ /\. { deny all; return 404; }`, which covers .git, .svn, and .env in one rule.
- Apache: refuse dot-directories via `RedirectMatch 404 /\..*$` in the site config, or block /.git/ in .htaccess where the config cannot be edited.
- CDN or edge: add the same deny rule at the edge as well. A rule that exists only on the origin does nothing for a path the CDN already has cached.
- Change the deployment: publish a build artefact rather than cloning into the document root, so the directory is not there to be served in the first place.
- Rotate every secret that ever appeared in the history: database passwords, API tokens, mail credentials, and anything in the remote URL. Treat them as public, because for as long as the directory was reachable they were.
- Then verify: re-run the deep audit and confirm the finding is gone.
Find out what a site leaves readable
The free passive scan covers headers, TLS, and known CVEs in seconds. Verifying domain ownership adds the active layer: exposed files, browsable directories, and admin surfaces, on a site whose owner asked for the check.
Check my websiteFAQ
- Does blocking /.git/ make the leak safe?
- It stops new downloads, and that is worth doing immediately. It does not help with copies already taken, and there is usually no way to tell whether any were. Any credential that appeared in the repository history has to be rotated for the incident to be closed.
- The .git folder is there but directory listing is off. Is that enough?
- No. Listing only controls whether a folder's contents are displayed. The files inside are still served to anyone requesting them by name, and the paths in a Git repository are entirely predictable, starting with /.git/HEAD and /.git/config.
- Why does CheckWeb not test for this on any site?
- Because requesting unlinked paths on a domain without permission is active probing, not passive reading, and doing it to third-party sites is what separates a scanner from an attacker. The check is available after domain ownership is verified, which is also why the free report never claims a site is clean of it.
- Does the same problem apply to .svn or .env files?
- Yes, and the deep audit checks those in the same group. A served .env is often worse per byte, since it holds current credentials rather than historical ones, while a Subversion working copy leaks source the way .git does.