Your .git Folder Is Public - Here's How Hackers Exploit It
One of the most devastating yet overlooked web vulnerabilities is an exposed .git directory. If an attacker can access /.git/ on your web server, they can reconstruct your entire source code, extract every credential ever committed, and read your complete development history. It takes minutes with freely available tools.
How Does a .git Folder End Up Publicly Accessible?
The .git directory is created in every Git repository. It contains the entire history of your project - every commit, every branch, every file that was ever tracked. When developers deploy code to a web server, the .git directory often comes along for the ride. Here is how it happens:
Direct Git Clone to the Web Root
The most common cause is deploying by running git clone or git pull directly in the web server's document root. This places the .git directory right alongside your public files. Unless the web server is explicitly configured to deny access to dotfiles, anyone can request https://yoursite.com/.git/config and the server will happily serve it.
Rsync or SCP Without Exclusion
Developers who deploy via rsync or scp from a local development environment often forget to exclude the .git directory. Running rsync -avz ./ user@server:/var/www/html/ copies everything, including .git/. Even if you later delete it, a single careless deployment can re-introduce it.
Docker or CI/CD Misconfigurations
Build pipelines that copy the entire project directory into a container without a proper .dockerignore file will include .git/. If the container serves files from the build context directory, the Git history is exposed. This is especially common with simple Dockerfile patterns like COPY . /app.
Hosting Providers with Default Configurations
Many shared hosting providers and default web server configurations do not block access to dotfiles. Apache's default configuration serves all files unless explicitly denied. Nginx similarly requires explicit location blocks to deny access to hidden directories.
What Attackers Can Extract from an Exposed .git Directory
An exposed .git folder is not just an information leak - it is a complete source code and credential disclosure. Here is exactly what an attacker can obtain:
Complete Source Code Reconstruction
Even if directory listing is disabled (so the attacker cannot browse /.git/ directly), they can still reconstruct your entire repository. Git stores objects in a predictable structure. By downloading /.git/HEAD, /.git/config, /.git/refs/heads/main, and then recursively fetching the commit objects, tree objects, and blob objects referenced within them, an attacker can rebuild every file in your repository.
Open-source tools like git-dumper, GitTools, and dvcs-ripper automate this process entirely. An attacker runs a single command and gets your full source code within minutes:
# Attacker's command to dump an exposed .git directory
git-dumper https://target.com/.git/ ./output-directory
# Or using GitTools
./gitdumper.sh https://target.com/.git/ ./output-directory
Credentials and Secrets
Git preserves the entire history of your project. Even if you removed a password from the codebase months ago, it still exists in a previous commit. Attackers specifically search the git history for:
- Database credentials - connection strings, usernames, and passwords
- API keys and tokens - AWS keys, Stripe keys, payment gateway credentials
- JWT signing secrets - allowing forged authentication tokens
- SMTP credentials - email server passwords used for phishing from your domain
- Private keys - SSH keys, SSL private keys, encryption keys
- Third-party service credentials - OAuth secrets, webhook URLs with tokens
Tools like truffleHog and git-secrets scan git history for high-entropy strings and known credential patterns. What takes a human hours to find takes an automated tool seconds.
Internal Infrastructure Details
The .git/config file alone reveals your remote repository URL (exposing your GitHub/GitLab organization and repo name), branch structure, and potentially credentials for private repositories. Commit messages and author information reveal developer names, email addresses, and internal project details that help map your organization.
Complete Development History
Every commit, every branch, every merge - the attacker can see your entire development timeline. This reveals when features were added, when security fixes were applied (and what they fixed), which areas of the codebase are actively developed, and which are neglected legacy code ripe for exploitation.
Is Your .git Folder Exposed?
The SecureBin Exposure Checker automatically scans for /.git/config and /.git/HEAD as part of its 19-point security assessment. Find out in seconds.
How to Check if Your .git Directory Is Exposed
Quick Manual Check
Open your browser and navigate to these URLs on your website:
https://yoursite.com/.git/HEAD- If this returnsref: refs/heads/main(or any branch reference), your .git directory is exposedhttps://yoursite.com/.git/config- If this returns Git configuration content, your repository details are public
If either URL returns content instead of a 403 Forbidden or 404 Not Found, you have a critical vulnerability that needs immediate attention.
Automated Scan
Use the SecureBin Exposure Checker to automatically test for exposed .git directories alongside 18 other security checks. The tool checks both /.git/config and /.git/HEAD and flags any exposure as a critical finding.
How to Block Access to .git Immediately
The fix must happen at the web server level. Simply deleting the .git directory works, but it will return the next time someone runs git pull. The permanent solution is to configure the web server to deny access to all hidden directories.
Nginx
# Block access to all hidden files and directories
location ~ /\. {
deny all;
access_log off;
log_not_found off;
return 404;
}
# Or specifically block .git
location ~ /\.git {
deny all;
return 404;
}
Apache (.htaccess)
# Block access to all hidden files and directories
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule "(^|/)\.(?!well-known)" - [F,L]
</IfModule>
# Alternative: deny specific directories
RedirectMatch 404 /\.git
RedirectMatch 404 /\.svn
RedirectMatch 404 /\.env
Express.js / Node.js
// Middleware to block dotfile access
app.use((req, res, next) => {
if (req.path.match(/(^|\/)\./)) {
return res.status(404).send('Not Found');
}
next();
});
IIS (web.config)
<configuration>
<system.webServer>
<security>
<requestFiltering>
<hiddenSegments>
<add segment=".git" />
<add segment=".svn" />
<add segment=".env" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
</configuration>
The Right Way to Deploy: Keeping .git Out of Production
Blocking web access is a necessary safeguard, but the best practice is to never have the .git directory on your production server in the first place.
Use Build Artifacts, Not Git Clones
Your CI/CD pipeline should build a deployment artifact (a tarball, zip, or Docker image) that contains only the files needed to run the application. The .git directory, tests, development dependencies, and documentation should be excluded from the artifact entirely.
Use .dockerignore
If you deploy with Docker, add .git to your .dockerignore file. This ensures the Git history is never copied into the container, even if your Dockerfile uses COPY . .. Use our .gitignore Generator to create proper ignore files for your stack.
# .dockerignore
.git
.gitignore
.env
.env.*
*.md
tests/
node_modules/
Use rsync with Exclusions
If you deploy via rsync, always exclude the .git directory:
rsync -avz --exclude='.git' --exclude='.env' --exclude='tests/' \
./build/ user@production:/var/www/html/
Use git archive for Clean Exports
Git has a built-in command to export a clean snapshot without the .git directory:
# Export current HEAD as a tar archive
git archive --format=tar HEAD | tar -x -C /path/to/deploy/
# Or create a zip file
git archive --format=zip HEAD > release.zip
What to Do If Your .git Was Already Exposed
If you discovered that your .git directory was publicly accessible, treat this as a security incident. The directory may have already been downloaded and its contents extracted. Take these steps immediately:
- Block access now: Apply the web server rules described above immediately
- Assume credentials are compromised: Rotate every secret that was ever committed to the repository - not just the ones currently in the code, but anything that appears in the git history
- Rotate database passwords and verify no unauthorized access occurred
- Rotate all API keys - AWS, payment gateways, email services, third-party integrations
- Rotate JWT signing keys and invalidate all existing sessions
- Regenerate SSH keys if any private keys were committed
- Check server access logs for requests to
/.git/paths to determine if the directory was actually accessed - Review your git history with
git log --all --diff-filter=D -- '*.env' '*.key' '*.pem'to find all deleted sensitive files that are still in history - Consider rewriting git history: If the repository is private and contains sensitive data in old commits, use
git filter-branchor BFG Repo-Cleaner to permanently remove secrets from history
Real-World Breaches Caused by Exposed .git Directories
This is not a theoretical risk. Major organizations have been compromised through exposed Git directories:
- DailyMotion (2016): An exposed
.gitdirectory on a subdomain led to the extraction of internal source code and credentials, contributing to a breach affecting 85.2 million user accounts - Multiple Indian government sites (2020): Security researcher Karan Saini discovered exposed
.gitdirectories on several Indian government websites, exposing source code and database credentials for citizen-facing applications - University websites: Bug bounty researchers regularly report exposed
.gitdirectories on university websites, finding student database credentials, email server passwords, and internal API keys - E-commerce sites: Thousands of online stores have been found with exposed
.gitdirectories containing payment processing credentials, customer database connections, and admin panel secrets
In 2019, a research team scanned the Alexa Top 1 Million websites and found that approximately 0.5% had exposed .git directories - that is 5,000 of the most popular websites on the internet leaking their source code to anyone who thought to look.
Scan for Exposed .git Now
Do not assume your server is configured correctly. The SecureBin Exposure Checker tests for /.git/config and /.git/HEAD automatically as part of a comprehensive 19-check security scan. Free, instant results.
Run Your Free ScanFrequently Asked Questions
My .git directory is exposed but directory listing is disabled. Am I safe?
No. Disabling directory listing prevents an attacker from browsing the .git/ folder, but it does not prevent them from downloading individual files if they know the paths. Git's internal structure is well-documented - attackers know exactly which files to request (HEAD, config, refs/heads/main, and then object files). Tools like git-dumper automate the reconstruction process without needing directory listing. You must explicitly deny access to the entire .git directory.
I removed sensitive data from my code. Is my git history still a risk?
Yes. Git stores every version of every file. If you committed a database password in commit A and removed it in commit B, the password still exists in commit A's objects. An attacker who downloads your .git directory can access every historical version of every file. The only way to truly remove data from git history is to use git filter-branch or BFG Repo-Cleaner - but if the .git directory was already exposed, assume the data was already extracted and rotate the credentials.
Does .gitignore protect against this vulnerability?
No. The .gitignore file prevents files from being tracked by Git, but it does not affect web server access. A .gitignore rule for .env prevents the .env file from being committed to the repository, but it does nothing to prevent the web server from serving the file. Web server access rules and Git tracking rules are completely separate concerns.
How does SecureBin Exposure Checker detect exposed .git directories?
The Exposure Checker sends HTTP requests to /.git/config and /.git/HEAD on your domain. If either responds with a 200 status code and content that matches Git's expected format (a branch reference in HEAD, or configuration directives in config), it flags the finding as critical. This is the same technique attackers use, but we only check - we do not download or extract any data.
Should I delete the .git directory from my production server?
If you deploy with git pull, deleting .git breaks your deployment workflow. The better approach is to keep the directory but block web access to it at the server level. If you use a CI/CD pipeline that builds deployment artifacts, then yes - the .git directory should never be included in the artifact and should not exist on the production server.
The Bottom Line
An exposed .git directory is one of the most severe web vulnerabilities because it gives attackers everything: your source code, your credentials, your development history, and your infrastructure details. The fix takes less than a minute - a single server configuration rule blocks access permanently. Check your site now, apply the fix, and make sure your deployment process never puts .git in harm's way again.
Related tools: Exposure Checker, .gitignore Generator, SSL Checker, DNS Lookup, CSP Builder, and 70+ more free tools.