Review Old Backup and Unreferenced Files for Sensitive Information
| ID |
|---|
| WSTG-CONF-04 |
Summary
Web servers commonly accumulate unreferenced or forgotten files: renamed old versions, editor/manual backups (file~, file.old, .bak), archives, and file-system “snapshots”. Because these often keep a different extension or name than the original (e.g. login.asp.old alongside login.asp), they tend to be served as plain text/source rather than executed, exposing server-side code, credentials, and internal details. The same problem now also shows up as forgotten objects left in cloud object storage (buckets/containers) backing an application or its deployment pipeline.
Threats
- Disclosure of credentials, internal paths, or other sensitive data via unreferenced include/config files.
- Access to powerful unreferenced functionality (e.g. an unlinked admin page).
- Exposure of vulnerabilities already fixed in the current version, via an old/backup copy that still contains them.
- Source code disclosure when a backup/copy of an executable file is served as plain text instead of executed.
- Bulk disclosure via backup archives containing many files at once (source, includes, compiled classes for decompilation).
- Sensitive data in log files (session IDs, URL parameters, admin activity).
- Forgotten backup/deployment artifacts (database dumps,
.tfstate,.envfiles) left in cloud object storage (buckets/containers), reachable directly without going through the application at all - see Cloud Object Storage Artifacts.
Test Objectives
- Find and analyze old, backup, and unreferenced files - including files exposed only through their extension, and objects left in cloud storage - that might contain sensitive information.
- Validate that no system or framework bypasses exist for any rules put in place to prevent these files from being served.
How to Test
Black-Box Testing
Testing for old, backup, and unreferenced files uses both automated and manual techniques, and typically involves a combination of the following. As a general principle, treat automated discovery as a way to generate a candidate list cheaply at scale, and always manually verify a sample of hits - automated tools report on status codes and fingerprints, not on whether a file actually contains sensitive data, and both false positives (custom “not found” pages returning 200) and false negatives (sensitive content behind an unexpected response code) are common.
Sensitive File Extensions
Submit requests with different file extensions and verify how they are handled, on a per-directory basis, since directories may be configured differently (for example, one directory may execute .php files while another serves them as plain text). Web server directories can be identified by scanning tools which look for well-known directories, and mirroring the site structure helps reconstruct the directory tree served by the application.
If the web application architecture is load-balanced or otherwise heterogeneous (for example, a mix of IIS and Apache nodes), assess all of the servers, since configuration may vary slightly between nodes and introduce asymmetric behavior or vulnerabilities.
Example
The tester has identified the existence of a file named connection.inc. Trying to access it directly gives back its contents, which are:
<?
mysql_connect("127.0.0.1", "root", "password")
or die("Could not connect");
?>
The tester determines the existence of a MySQL DBMS backend and the weak credentials used by the web application to access it.
The extensions and paths worth checking for fall into different categories, which matter because they carry different levels of risk and require different handling once found. A hit in any category is a candidate finding only - confirm the response actually returns the file’s content (not a custom 404 or an access-denied page), and read enough of that content to confirm it is genuinely sensitive, before reporting it. This is especially important for the “may be legitimately served” and “sensitivity depends on content” categories below, where the mere presence of the extension is not itself a finding.
| Type | Category | Examples |
|---|---|---|
| Credentials and secrets | Should generally never be publicly served | .env, .pem, .key, .p12, .pfx, .tfstate, .tfvars, .kdbx, .htpasswd, .npmrc, .dockercfg/.docker/config.json, .asa, .inc, .config |
| Source/configuration | Should generally never be publicly served | .java source files, .yaml/.yml and .json outside expected API paths (Kubernetes manifests, CI pipeline definitions, docker-compose.yml) |
| Backups and archives | Should generally never be publicly served | .bak, .old, .orig, .save, .swp, ~ (editor backups), .zip, .tar, .gz, .tgz, .rar, .7z |
| Data artifacts | Sensitivity depends heavily on content | .db, .sqlite, .sqlite3, .parquet, .avro, .csv, .ipynb (notebooks in particular can contain hardcoded credentials in cell output, but frequently don’t) |
| May be legitimately served | May be legitimately served | .txt, .md, .log, .pdf, .docx, .rtf, .xlsx, .pptx |
| Special paths (not file extensions) | Directory names and paths, not extensions | .git/, .docker/ |
The list given above details only a few examples, since file extensions and filenames worth checking are too numerous to be comprehensively treated here. Refer to FILExt for a more thorough extension database, and see SecLists’ raft/common backup/config wordlists for maintained, up-to-date filename lists to drive automated discovery.
To identify files with a given extension, use a mix of vulnerability scanners, spidering/mirroring tools, search-engine queries (see Testing: Spidering and googling), and manual inspection, since manual review overcomes gaps in automated spidering (for example, links that only appear after client-side JavaScript execution).
Windows 8.3 Legacy Filename Handling
On Windows-based systems, legacy 8.3 short filename generation can affect how files are resolved and accessed by the web server, independent of any file-upload logic. In environments where 8.3 filename generation is enabled, sensitive files that are not directly reachable by their long filename may still be reachable through their shortened equivalent, which can disclose source code or configuration files even when access controls correctly block the long filename.
Examples of 8.3 filename resolution behavior that may lead to unintended file exposure:
- A file such as
file.phtmlmay be processed as PHP code. - A corresponding shortened filename (for example,
FILE~1.PHT) may be accessible depending on server and handler configuration. - Files with misleading or extended filenames may still resolve to executable handlers once expanded by the operating system.
Testing should focus on whether legacy filename handling allows access to sensitive files that were not intended to be served this way; testing of file upload mechanisms themselves is covered separately under File Upload and Business Logic test cases.
Inference from the Naming Scheme Used for Published Content
Enumerate all of the application’s pages and functionality, manually or with a spidering tool. Most applications use a recognizable naming scheme and organize resources into pages and directories using words that describe their function, so it is often possible to infer the name and location of unreferenced pages from the naming scheme used for published content. For example, if a page titled viewuser.asp is found, one should also look for edituser.asp, adduser.asp, and deleteuser.asp. Similarly, if a directory /app/user is discovered, one should also search for /app/admin and /app/manager.
Other Clues in Published Content
Many web applications leave clues in published content that can lead to the discovery of hidden pages and functionality. These clues can often be found in the source code of HTML and JavaScript files, which should be manually reviewed to identify such clues. For example:
Programmers’ comments and commented-out sections of source code may refer to hidden content:
<!-- <A HREF="uploadfile.jsp">Upload a document to the server</A> -->
<!-- Link removed while bugs in uploadfile.jsp are fixed -->
JavaScript may contain page links that are only rendered within the user’s GUI under certain circumstances:
var adminUser=false;
if (adminUser) menu.add (new menuItem ("Maintain users", "/admin/useradmin.jsp"));
HTML pages may contain FORMs that have been hidden by disabling the SUBMIT element:
<form action="forgotPassword.jsp" method="post">
<input type="hidden" name="userID" value="123">
<!-- <input type="submit" value="Forgot Password"> -->
</form>
Another source of clues about unreferenced directories is the /robots.txt file used to provide instructions to web robots:
User-agent: *
Disallow: /Admin
Disallow: /uploads
Disallow: /backup
Disallow: /~jbloggs
Disallow: /include
Blind Guessing
In its simplest form, this involves running a list of common filenames through a request engine in an attempt to guess files and directories that exist on the server. The following netcat wrapper script will read a wordlist from stdin and perform a basic guessing attack:
#!/bin/bash
server=example.org
port=80
while read url
do
echo -ne "$url\t"
echo -e "GET /$url HTTP/1.0\nHost: $server\n" | netcat $server $port | head -1
done | tee outputfile
Depending upon the server, GET may be replaced with HEAD for faster results. The output file specified can be grepped for “interesting” response codes. The response code 200 (OK) usually indicates that a valid resource has been found (provided the server does not deliver a custom “not found” page using the 200 code). But also look out for 301 (Moved), 302 (Found), 401 (Unauthorized), 403 (Forbidden) and 500 (Internal error), which may also indicate resources or directories that are worthy of further investigation.
The basic guessing attack should be run against the webroot, and also against all directories that have been identified through other enumeration techniques. More advanced/effective guessing attacks can be performed as follows:
- Identify the file extensions in use within known areas of the application (e.g. JSP, ASPX, HTML), and use a basic wordlist appended with each of these extensions (or use a longer list of common extensions if resources permit).
- For each file identified through other enumeration techniques, create a custom wordlist derived from that filename. Get a list of common file extensions (including
~,bak,txt,src,dev,old,inc,orig,copy,tmp,swp,env,save, etc.) and use each extension before, after, and instead of, the extension of the actual filename.
Note: Windows file copying operations generate filenames prefixed with “Copy of “ or localized versions of this phrase, hence they do not change file extensions. While “Copy of “ files typically do not disclose source code when accessed, they might yield valuable information in case they cause errors when invoked.
Information Obtained Through Server Vulnerabilities and Misconfiguration
The most obvious way in which a misconfigured server may disclose unreferenced pages is through directory listing. Request all enumerated directories to identify any which provide a directory listing.
Numerous vulnerabilities have been found in individual web servers which allow an attacker to enumerate unreferenced content, for example:
- Apache
?M=Ddirectory listing vulnerability. - Various IIS script source disclosure vulnerabilities.
- IIS WebDAV directory listing vulnerabilities.
Use of Publicly Available Information
Pages and functionality in internet-facing web applications that are not referenced from within the application itself may be referenced from other public domain sources. There are various sources of these references:
- Pages that used to be referenced may still appear in the archives of internet search engines. For example,
1998results.aspmay no longer be linked from a company’s site, but may remain on the server and in search engine databases. Thesite:Google search operator may be used to run a query only against the domain of choice, such as in:site:www.example.com. Using search engines in this way has led to a broad array of techniques described in theGoogle Hackingsection of this Guide. Backup files are not likely to be referenced by any other files and therefore may not have been indexed, but if they lie in browsable directories the search engine might know about them. - Google and other search engines keep cached versions of pages found by their crawlers, which may still reference or hint at additional hidden content even after the original page is removed.
- Content that is not referenced from within a target application may be linked to by third-party sites. For example, an application which processes online payments on behalf of third-party traders may contain a variety of bespoke functionality which can (normally) only be found by following links within the sites of its customers.
- Public code-hosting and CI/CD build-log search (GitHub/GitLab code search, and cached CI logs) can surface references to internal filenames, paths, or bucket names committed by mistake.
Filename Filter Bypass
Because deny list filters are based on regular expressions, one can sometimes take advantage of obscure OS filename expansion features which work in ways the developer didn’t expect. The tester can sometimes exploit differences in ways that filenames are parsed by the application, web server, and underlying OS and its filename conventions.
Example: Windows 8.3 filename expansion c:\program files becomes C:\PROGRA~1
- Remove incompatible characters
- Convert spaces to underscores
- Take the first six characters of the basename
- Add
~<digit>which is used to distinguish files with names using the same six initial characters - This convention changes after the first 3 name collisions
- Truncate file extension to three characters
- Make all the characters uppercase
Cloud Object Storage Artifacts
The same “forgotten file” problem reappears in cloud object storage backing a web application, its static assets, or its deployment pipeline (AWS S3, Azure Blob Storage, Google Cloud Storage). This subsection covers only the forgotten-artifact discovery angle; for bucket/container ACL, IAM policy, and signed-URL depth, see Cloud Storage.
- Identify buckets/containers associated with the target through naming conventions (
<company>-backup,<company>-assets,<company>-logs,<company>-dev,<app>-uploads), DNS records (CNAMEs pointing at storage endpoints - see also Subdomain Takeover), and references found in JS bundles, error messages, or CI configuration. - Common forgotten artifact types in buckets mirror the extension list above, with a few storage-specific additions:
terraform.tfstatefiles,.envfiles uploaded as part of a deploy step, database snapshot exports, and CI/CD build artifacts (compiled binaries or archives containing embedded secrets). - Once a candidate object or listing is found, manually verify content before reporting - an object named
backup.sqlthat turns out to be empty or a placeholder is not a finding; confirm the actual data present is sensitive. - Tools such as S3Scanner and cloud_enum automate discovery across the major providers, but as with on-server discovery, treat hits as candidates requiring manual confirmation, not findings in themselves.
Gray-Box Testing
Gray-box testing against old and backup files, and against file extension handling, involves examining the server/application configuration directly rather than only probing from outside:
- Examine files within the directories served by the web server(s) comprising the application infrastructure. Since copies/backup files tend to follow predictable naming conventions (editor-specific backup suffixes,
.old/.bak-style human-made copies), this search can be scripted; a useful strategy is a periodically scheduled job checking for such extensions, combined with less frequent manual checks. - Review server configuration to confirm which extensions are served as which content type/handler, on a per-directory basis, and confirm this matches intent (for example, that a directory containing
.incor.configfiles is not web-accessible at all). - If the application relies on load-balanced or heterogeneous infrastructure, determine whether this introduces inconsistent behavior between nodes.
- Where the tester has access to cloud infrastructure configuration, review bucket/container policies and ACLs directly (see Cloud Storage for the dedicated ACL/IAM/signed-URL checks) rather than relying solely on external probing.
Remediation
For an effective protection strategy, testing should be combined with a security policy that clearly forbids dangerous practices, including:
- Editing files in-place on the web server or application server file systems. This is a particularly bad habit, since it is likely to generate backup or temporary files by the editors. If you absolutely need to edit files on a production system, ensure that you don’t leave behind anything that is not explicitly intended, and keep in mind that you are doing it at your own risk.
- Carefully check any other activity performed on file systems exposed by the web server, such as ad hoc administration activities (for example, zipping directories for a quick backup and leaving the archive behind).
- Adopt configuration management policies that prevent obsolete and unreferenced files from accumulating in served directories.
- Design applications so they do not create or rely on files stored under the web directory trees served by the web server. Data files, log files, configuration files, etc. should be stored in directories not accessible by the web server, to prevent both information disclosure and, where permissions allow writing, data modification.
- Ensure file system snapshots are not accessible via the web if the document root is on a file system using this technology. For example, under Apache, a location directive like this should be used:
<Location ~ ".snapshot">
Order deny,allow
Deny from all
</Location>
- Configure web servers/directories to serve each file extension with the intended handler (or not at all), on a per-directory basis, and validate this after infrastructure changes in load-balanced/heterogeneous environments.
- For cloud object storage, disable public listing and public read by default, and use scoped IAM policies rather than bucket-wide public grants; treat any bucket used for backups, logs, or deployment artifacts as sensitive by default.
Tools
Vulnerability assessment tools tend to include checks to spot web directories having standard names (such as “admin”, “test”, “backup”, etc.), and to report any web directory which allows indexing. If the tester is unable to find directory listing, they should try to check for probable backup extensions. Some tools that can help with this include:
Web spider tools
Modern Alternatives
- Burp Suite - widely used web security testing proxy
- ZAP - open-source web application security testing tool, including forced browse/spidering for this class of issue
- ffuf - fast web fuzzer, well suited to backup/extension wordlist-based discovery
- Screaming Frog SEO Spider - website crawler and broken link checker
Cloud Object Storage Discovery
Some of these are also included in standard Linux distributions. Web development tools usually include facilities to identify broken links and unreferenced files.