Description
Source code disclosure occurs when an application inadvertently serves its own source files to external clients. This can happen through misconfigured web servers, version control artefacts left on public hosts, backup files with predictable names, or framework-level debug endpoints. CWE-540 captures the class of issues where sensitive information is embedded in and retrievable from source files.
The vulnerability is rarely exploitable on its own, but it dramatically lowers the cost of every subsequent attack. An attacker who can read application code can identify hardcoded credentials, map internal API routes, understand input validation logic, and target specific library versions with known CVEs — all without generating meaningful server-side noise.
Source code disclosure is consistently flagged under A05:2021 — Security Misconfiguration because it almost always results from a deployment oversight rather than an inherent flaw in the language or framework.
How It Works
The most common vectors include:
Version control directories — deploying a Git repository root to a public web server exposes .git/config, .git/HEAD, and packed object files. An attacker can reconstruct the full repository using tools like git-dumper or GitTools:
git-dumper https://example.com/.git/ ./recovered-repo
Editor and IDE backup files — many editors write backup copies with predictable suffixes. A request for index.php~, config.bak, or wp-config.php.save can return raw PHP source instead of executing it:
GET /includes/db.php.bak HTTP/1.1
Host: example.com
Web server misconfiguration — Apache or Nginx misconfigurations can cause .php files in certain directories to be served as plain text rather than passed to the PHP interpreter.
Framework debug endpoints — some frameworks expose a source viewer when DEBUG=True is set in production. Django's debug 500 pages include local variable values and code excerpts.
Impact
- Credential exposure — database passwords, API keys, and private keys embedded in source code become immediately accessible.
- Attack surface mapping — internal routes, admin panels, and hidden parameters are revealed, eliminating reconnaissance effort.
- Business logic bypass — understanding validation code allows attackers to craft inputs that pass checks without meeting intended conditions.
- Dependency enumeration —
package.json,composer.json, orrequirements.txtfiles identify exact dependency versions for targeted CVE exploitation. - Accelerated chained attacks — source disclosure is rarely the final objective but consistently reduces time-to-exploitation for SQL injection, RCE, and authentication bypass.
Detection
- Check for version control artefacts — request
/.git/HEAD,/.svn/entries, and/.hg/requires. A 200 response with recognisable content confirms exposure. - Fuzz for backup extensions — append
.bak,.old,.orig,~,.swp, and.saveto known filenames. Tools likeffufandferoxbustersupport extension brute-forcing natively. - Test framework debug modes — trigger a deliberate 500 error and inspect the response for stack traces containing file paths or source excerpts.
- Check
/.env— Laravel, Next.js, and many other frameworks store secrets in.envfiles that are sometimes deployed to web roots. - Search for exposed
composer.lockorpackage-lock.json— these exact-version manifests confirm library versions without requiring source access.
Remediation
Remove version control directories from web roots. Configure the web server to return 403 for .git, .svn, and .hg paths, or — better — ensure these directories are never deployed to the document root.
Implement build pipelines. Deploy compiled artefacts rather than raw source trees. Build tools like Webpack, Vite, and standard CI pipelines can be configured to exclude development files.
Configure file extension handling. Ensure the web server never serves .php, .py, .rb, or .env as static text. Allowlist served file types rather than blocklisting dangerous ones.
Rotate all credentials found in source history. A .git exposure invalidates every secret in the repository's full commit history, not just the current HEAD.
