Exposed .git Directory
A production deploy left the whole repository in the web root, so /.git/ is browsable. An attacker dumps it, rebuilds the source, and reads the database password. Block /.git, deploy built artifacts instead of the repo, and rotate the secrets.
What Is Exposed .git Directory?
An exposed .git directory is a source-code disclosure flaw that happens when a deploy copies the entire Git repository, including the .git folder, into the web root of a production server. Because .git records the complete history of a project, not just its current files, anyone who can browse or download it can reconstruct the full source tree and read any secret that was ever committed. It is distinct from secrets that sit in the commit history of a properly hosted repository, which require access to that repository; here the repository itself is served over the public web from the site's own document root, reachable by anyone with the URL. This exercise puts you on both sides. As Bob, an attacker who probes public web servers for misconfigured paths, you request /.git/ on app.verlune.io and get a browsable directory listing with .git/config sitting in the web root, realize the whole repository was deployed there, run git-dumper to pull the folder down and rebuild the source tree, and read the recovered config to find a database password and a live API key. As Alice, a site reliability engineer at Verlune who owns the deploy pipeline, you receive a monitoring alert that /.git/config is publicly reachable, confirm the deploy copied the whole working tree into the docroot, block /.git at the web server as an immediate stop-gap, then fix the deploy to ship built artifacts instead of the repository and rotate the exposed credentials before filing the incident report. The exercise closes with quiz questions on what an exposed .git lets an attacker do, why blocking the URL alone is not enough, and why .git holds the full history rather than only the current files.
What You'll Learn in Exposed .git Directory
- Recognize an exposed .git directory: a deploy that ships the whole repository to the web root turns a public URL into a full source and history disclosure
- Trace the attack from a browsable /.git/ listing and a readable .git/config, to a git-dumper pull that reconstructs the source tree, to secrets recovered from the committed configuration
- Understand that .git holds the entire commit history, so credentials that were changed or deleted in later commits remain recoverable from an exposed repository
- Apply the durable fix: deploy built artifacts rather than the repository so .git never reaches production, and rotate every credential the exposure revealed
- Distinguish server-side exposure of a repository over the web from secrets sitting in the commit history of a hosted repository, and treat blocking the /.git URL as a stop-gap rather than a complete fix
Exposed .git Directory — Training Steps
-
Size up the target
Today Bob is targeting Verlune, a product-analytics company whose dashboard runs at app.verlune.io. He starts where anyone would, on the public site, getting a feel for what the company ships before he looks for a way in. The app itself gives little away. The interesting mistakes are usually in the paths a site never meant to answer.
-
A path that should not answer
Bob requests /.git/ directly on the same host, a path a well-configured server would never expose. Instead of a 404, the server answers with a browsable directory listing. The internal files of a Git repository, HEAD , config , objects , are all sitting in the web root, served like any other page.
-
It is a real repository
Bob clicks the config file in the listing. It reads back as an ordinary Git config: the remote origin, the default branch, the user settings. This is not a stray file someone left behind. The whole working repository shipped to production, so its full history is one download away.
-
Reconstruct the source
Bob does not click through the listing by hand. He points a dumping tool at the exposed folder, which walks the objects it serves and rebuilds the working tree exactly as it exists in the repo. Within seconds he has the full source of Verlune's app on his own machine, history and all.
-
Credentials in the source
With the source rebuilt, Bob opens the recovered database config. The most valuable things in a leaked repo are rarely the code itself, they are the secrets committed alongside it. He does not have to look hard.
-
A password and a key
The recovered file hands Bob two live secrets in plain text: the production database connection string, password included, and an API key for the admin API. Both were committed straight into source, which is why an exposed repository leaks them.
-
Connect with the leaked credentials
A leaked credential is only a theory until it opens something. The recovered config hands Bob a full database connection string, host, name, user, and password, so he opens a SQL client and connects straight to Verlune's production database with it. No exploit and no stolen session: the database trusts the password the repository gave away.
-
The customer table is open
Connected. Bob runs the obvious query and the production customers table comes back in full: names, emails, plans, and billing. He is reading Verlune's live customer records straight from the database, with no account of his own.
-
Knowledge check
You just watched a single public URL hand over the whole source tree and its secrets. Lock in why.
-
The monitoring alert
You own Verlune's web deploy pipeline. Overnight, the monitoring check that watches for sensitive paths on production fired: it fetched .git/config on app.verlune.io and got a 200. Security operations emailed you the finding.