My .git/index file got exposed. What should I do?
The .git/index file is a binary manifest of every file your repository tracks — complete with SHA-1 object hashes. If it's publicly reachable, automated tools like git-dumper can reconstruct your entire source code in minutes. Here's exactly what that means and what to do about it.
First: block access to the entire .git/ directory — right now.
The index file alone maps every object in your repository. If the object store (.git/objects/) is also reachable, an attacker already has — or can fetch — a complete copy of your source code. Blocking the directory is step zero, before anything else.
// the 60-second version
- Block public access to the entire
.git/directory at the web server level immediately. - Check whether
.git/objects/is also accessible — if so, your source code is fully reconstructable. - Assume every secret ever committed to that repo is now public — rotate all credentials.
- Never deploy with the
.git/directory inside the web root again.
01Understand what the .git/index reveals
Git's index file (also called the staging area) starts with the magic bytes DIRC and stores a sorted list of every file that Git is tracking in the working tree. For each file it records:
- The full file path relative to the repository root — so an attacker instantly knows your directory structure, framework, and file naming conventions.
- The SHA-1 object hash for the current content of that file — the key that unlocks the corresponding blob object in
.git/objects/. - File mode and size — enough to reconstruct a working clone.
The index alone is a map. Combined with the object store, it's a full copy. Tools like git-dumper and GitHacker are designed to exploit exactly this: they read the index to discover every object hash, then fetch each blob from .git/objects/xx/yyyyyy… to reconstruct the files on disk.
git-dumper is widely used by bug hunters and attackers. If your index was reachable for more than a few minutes, assume it was found. Automated scanners look for .git/HEAD and .git/index constantly — these are among the most common misconfiguration checks.
02Block public access to the .git/ directory
The web server should never serve anything from .git/. If you're on Nginx, add a location block that covers the entire directory:
location ~ /\.git { deny all; return 404; }
For Apache, in your virtual host config or .htaccess:
RedirectMatch 404 /\.git
After reloading the web server, verify from outside your network that /.git/index, /.git/HEAD, and /.git/config all return 403 or 404 — not file contents.
The real fix is to never deploy the .git/ directory into the web root. Blocking it at the web server is a safety net — not the long-term solution. See step 5.
03Check whether git objects are also accessible
The index is only useful to an attacker if the objects it references are also reachable. Test whether your object store is open by constructing a known object path. First, parse a SHA hash from the index:
# requires the git-index-format parser or git itself git ls-files --stage | head -5 # output: <mode> <sha1> <stage> <path> # e.g.: 100644 a1b2c3d4e5f6… 0 src/config.php
Then check whether that object is fetchable via HTTP:
curl -o /dev/null -s -w "%{http_code}" \
https://example.com/.git/objects/a1/b2c3d4e5f6…
A 200 response means your source code is fully reconstructable. A 403 or 404 means the index leaked metadata but the file contents may still be safe — though you should still treat any secrets in the codebase as exposed if the index was readable for any meaningful time.
04Assess what your source code would reveal
Whether or not an attacker successfully cloned your repository, you need to understand what was at risk. Walk through your codebase with the mindset of someone seeing it for the first time:
- Hardcoded credentials — database passwords, API keys, or tokens committed directly into source files. These are now fully exposed.
- Configuration files — any file ever committed with secrets, even if since deleted (git history preserves them in the object store).
- Business logic and proprietary algorithms — attackers can study how your app works to find further vulnerabilities.
- Internal endpoints and admin paths — routes, admin URLs, and internal API paths that shouldn't be public knowledge.
Run a secrets scan against your full git history to find everything that could have leaked:
# using trufflehog (recommended) trufflehog git file://. --since-commit HEAD~100 # or gitleaks gitleaks detect --source=. --log-opts="HEAD"
Rotate every credential the scan finds — and any that you know are in the codebase even if the scanner misses them.
05Prevent it from happening again
The root cause is deploying a live .git/ directory into the web-accessible document root. There are several approaches to eliminate this permanently:
- Separate your build output from your repository. Deploy only the built artefacts to the web root — not the entire working tree. Use a CI/CD pipeline that copies only what needs to be served.
- Use
--no-checkoutor a deploy key that only touches specific paths. Pull code to a directory above the web root and symlink or copy only the public-facing files. - Add a web server deny rule as a defence-in-depth measure even after you've fixed the deployment (step 2). If a future deploy goes wrong, the web server is the last line of defence.
- Add monitoring for
/.git/requests in your WAF or log alerting. Any hit should trigger an immediate review.
If personal user data was stored in your database and the source code exposure led to a credential being used to access it, you may have GDPR or breach-notification obligations. Document the exposure window and consult your legal/compliance team.
Was this guide useful?
These playbooks are free to read and share. If a heads-up ever saved you a bad week, you can say thanks — or jump into the other guides.