Git Exposure Checker

Sends two real HTTP GET requests to a site you choose -- .git/HEAD and .git/config -- and checks whether the response bodies are real git-internal content, not just whether the status code is 200. A publicly readable .git directory lets anyone reconstruct your entire committed source history, including files and secrets removed in a later commit, using a free tool such as git-dumper or GitTools. Only point it at a system you own or are authorised to test.

See this checker vs. checking the URL by hand -- the two ways a manual look gets it wrong.

1. Run the CLI against your site

Node.js, no dependencies to install:

node check.mjs https://example.com/ --json

Get check.mjs, probe.mjs, and analyze.mjs from the repo — plain Node, nothing to install. It only ever talks to the URL you pass; nothing goes through this site. Pass the site root (a trailing slash matters) unless you specifically want to check a subpath's own .git directory.

2. Paste the JSON output here

Paste the JSON from step 1 and click Check.

Common questions

What can someone actually do with an exposed .git directory?

A tool such as git-dumper or GitTools can reconstruct the entire repository from the raw files a webserver serves under .git/ -- not just the current checkout, but the full commit history. That includes any file or secret that was ever committed and later removed in a subsequent commit: an API key rotated out of the code, a config file with a database password, an internal comment. A live directory listing of the deployed site would never show any of that, because it was deleted before deploy -- it is only present in the git history the .git directory carries.

Why does this check the response body instead of just the HTTP status code?

Because a bare status check produces false positives on a common pattern: a webserver or CDN configured to answer every unknown path with a 200-status custom error page (a "soft 404"), rather than a real 404. Under a status-only check, that server would incorrectly report .git/HEAD as "exposed" for every site behind it. This tool instead checks that the response body is exactly what a real .git/HEAD file contains (a "ref: refs/heads/..." line, or a bare 40-character commit SHA for a detached HEAD) and that .git/config contains the [core] section every real git config opens with -- content no generic error page would happen to produce.

Why only .git/HEAD and .git/config, and not the rest of the repository?

Those two are small (normally well under 200 bytes each), and matching real git-internal content in either is already conclusive: if HEAD or config is exposed, the rest of the .git directory almost always is too, since a webserver serving one static file under a path normally serves every file under it. Reading further -- the object database, packed refs, the full index -- would start to look like this tool downloading the repository itself rather than checking whether it is exposed, which is a different, higher-liability action this tool deliberately does not take.

Why does this need a CLI instead of just checking a URL I type into the page?

Checking an arbitrary third-party URL from inside a browser tab runs into CORS restrictions the target site's own headers control, and a page that could reach any URL a visitor types would itself be a server-side request forgery risk. A small local CLI with no such restriction, run from your own machine, is the same shape every other tool in this class (curl, git-dumper, GitTools) uses.

Does a clean report mean my site has no exposed secrets?

No. This checks one specific, well-documented exposure class -- a publicly readable .git directory at the path you point it at. It does not check other common source-control or backup exposures (a stray .svn directory, a .env file, a database dump left in the webroot), does not crawl the rest of the site, and only checks the one base URL you give it, not every subpath a real deployment might serve from. Treat a clean report as evidence about this one exposure class at this one path, not a full security assessment.

How to tell a real exposed .git directory from a soft-404 false positive -- the actual response bytes for both cases, side by side.