Skip to content

Sensitive files check

Find out whether your website publicly serves files that do not belong there: a .git repository, .env configuration, database backups or logs. We explain how to verify a finding and what to do about it.

Loading verification…

What the check verifies

Deployments easily put files on the server that do not belong there: a whole .git directory, an .env file with the database password, a forgotten backup or a log. The web server then serves them to anyone who knows the name. Bots try these paths on every website they can reach, so you cannot rely on nobody knowing the file is there.

The tool asks your server for a fixed list of more than 30 common paths and checks whether the server serves each one. It reads at most the first 4 KB of each response to tell a real file from an ordinary page of the website. We do not store or display the content.

  • Version control: /.git/HEAD, /.git/config and /.svn/entries. An exposed repository lets anyone download the source code and its full history, often including passwords that were committed at some point.
  • Configuration and secrets: /.env, /.env.local, /.env.production, /config.php, /config.json and backup copies of wp-config.php ending in .bak or .old.
  • Backups and exports: /backup.sql, /database.sql, /db.sql, /backup.zip, /backup.tar.gz and /.htaccess.bak.
  • Debug and server files: /phpinfo.php, /info.php, /test.php, /debug.log, /error.log, the /server-status page and the /.htpasswd and /web.config files.
  • Other development leftovers: /package.json, /package-lock.json, /composer.json, the /node_modules/, /vendor/ and /.vscode/ directories, the /.DS_Store and /Thumbs.db system files and, for WordPress, /xmlrpc.php and /wp-admin/.
  • Standard files: /robots.txt, /sitemap.xml and /.well-known/security.txt. These are files a website should have.

How to read the result

We check the address your website actually runs on. If the address you enter redirects, for example from HTTP to HTTPS or to the www version, we test the destination. All paths are tested from the root of the domain.

Many websites answer any unknown address with status 200 and their home page, so the status code alone is not enough. A response sent as HTML (text/html) is never counted as the .env file or backup we are looking for. For each type of path, we also request a random address of the same shape (same directory, extension and leading dot). A response counts only if the server turns the random address away (404, 410 or a redirect to another website) or answers it differently from the path we are checking. We ignore the address itself, which some websites repeat in their response. If the server answers the random address with an error or a rate limit, a finding cannot be confirmed. Pages the server generates, such as phpinfo(), /server-status or a directory listing, are recognized by their typical content.

  • Publicly accessible: the server served the path, and the response looks like a real file or a generated page. Verify the finding using the steps below.
  • Not accessible: the server returned 404 or 410, redirected away from your website or sent only an ordinary page of the website. For config.php, this also applies when the script exists but the server runs it and does not reveal its source code.
  • Access denied: the server answered 401 or 403. Usually this is your own rule protecting the file, but a firewall blocking our requests answers the same way.
  • Not verified: the server returned an error, a rate limit (such as 429) or a redirect that led nowhere, did not respond within 5 seconds, a bot-protection check answered instead of the website, or the response did not reliably show whether the file exists. Paths left unchecked because the whole check has a time limit are also marked as not verified. This result says nothing about whether the file is on the server. If it happens for most paths, we warn you that the result is incomplete.
  • Reachable, consider restricting: the WordPress admin (/wp-admin/) or the /xmlrpc.php interface. They are public by design and not a leaked file, but bots use them to guess passwords.
  • Standard files: for robots.txt, sitemap.xml and security.txt, being found is what you want. A redirect to another website, which RFC 9116 allows for security.txt and which is common for sitemaps on a CDN, counts as found. A missing file does not weaken security, but we recommend adding security.txt.
Path                          Server response                       Result
/.tunasec-random-path         404, text/html                        (comparison)
/.env                         200, text/plain: DB_PASSWORD=…        Publicly accessible
/sitemap.xml                  200, text/html: home page             Not found
/.git/HEAD                    403                                   Access denied (HTTP 403)
/backup.sql                   429                                   Not verified (HTTP 429)
/wp-admin/                    302 → /wp-login.php, 200              Reachable, consider restricting
  • The random path shows how the server answers for missing files shaped like /.env, with a leading dot and no extension. Here it returned 404.
  • /.env returned 200 with content that is not an HTML page, while the random address of the same shape returned 404, so the tool marks it as publicly accessible.
  • /sitemap.xml returned 200, but only with the home page. There is no sitemap at this address, even though the status code suggests otherwise.
  • /.git/HEAD returned 403: the server denied access. A 404 is slightly better because it does not reveal whether the directory exists.
  • /backup.sql returned 429: the server temporarily rate-limited us. We know nothing about the backup, so check it another way, for example with the command in the steps below.

What to do if the tool finds something

  1. Check what the server actually serves

    Open the address in a browser or run curl -s https://your-company.com/.env | head -n 5. If you see passwords, keys, SQL statements or, for .git/HEAD, a line like ref: refs/heads/main, the file really is public. Use the same command to check paths the tool marked as not verified.

  2. Block access

    Remove the file from the web directory, or deny access in the server configuration as in the example below. Backups, database exports and logs belong outside the directory the server serves. Delete debug scripts such as phpinfo.php. Then run the check again.

  3. Replace every secret that was exposed

    Deleting the file is not enough, because someone may already have a copy. Change database passwords, API keys, SMTP and cloud credentials and application keys such as APP_KEY or SECRET_KEY. If .git was exposed, assume the attacker has the source code and everything that was ever in its history.

  4. Find out whether anyone downloaded the file

    Search your access logs for requests to the path that returned 200, for example /.env or /.git/. If your logs only go back a few days, finding nothing proves nothing. If personal data may have leaked, assess whether you must report the breach to your data protection authority within 72 hours of becoming aware of it, as the GDPR requires.

  5. Change your deployment so it does not happen again

    Deploy only the build output, not a working copy of the repository: a CI artifact, or rsync excluding .git and .env. Point the web root at a subdirectory such as public/ so configuration and dependencies stay outside it. If a secret was committed, remove it from the history with git filter-repo, but after rotating the keys, not instead of it.

# nginx – inside server { }, before other regex locations
# hidden files and directories (.git, .env, .htpasswd) except .well-known
location ~ /\.(?!well-known/) {
    return 404;
}
# backups, database exports and logs
location ~* \.(sql|bak|old|log)$ {
    return 404;
}

# Apache 2.4 – site configuration or .htaccess
RedirectMatch 404 "/\.(?!well-known/)"
<FilesMatch "\.(sql|bak|old|log)$">
    Require all denied
</FilesMatch>
  • nginx evaluates regex location blocks in the order they appear and uses the first match. Put these rules before other regex blocks, such as the one that handles PHP.
  • The .well-known exception is necessary, otherwise you also block security.txt and Let’s Encrypt certificate validation.
  • return 404 does not reveal that the file exists. deny all in nginx or Require all denied in Apache returns 403, which protects the file just as well but confirms that it exists.
  • In Apache, restrict /server-status with Require local or Require ip and your administrators' addresses. Blocking in the configuration is a safety net: backups and logs do not belong on the web server at all.

What the check cannot tell you

  • We test only a fixed list of paths. Files with other names, such as backup-2025.zip or .env.bak, will not be found. We do not crawl the website or guess other names.
  • We test only the root of one domain. If you enter an address with a path, the path is ignored. Check other subdomains, such as admin.your-company.com, separately.
  • A finding is based on the first 4 KB of the response. We therefore do not know which secrets a file contains, and we do not count a file that the server sends as HTML (text/html).
  • A script without recognizable output, such as test.php, can only be assessed reliably on websites that answer addresses that do not exist with 404 or 410. On other websites, we mark it as not verified unless its response is the same as the one for a random address.
  • If the server returns an error, does not respond within 5 seconds, or a firewall or bot protection (for example from Vercel or Cloudflare) blocks our requests, the path is marked as not verified or access denied. The whole check is also limited to about 25 seconds, and paths left without time are marked as not verified too. That does not mean the file is not on the server.
  • Finding nothing does not mean the website is secure. Only a penetration test reveals vulnerabilities in the application, its login or its API.
  • We connect only to public addresses, including after redirects. We do not store the result or the content of responses, and each IP address can run at most five checks per minute.

Common questions

Why does the tool suggest restricting /wp-admin/ when the website works normally?

On WordPress, this address redirects to the login page, so it is reachable by design and is not a leaked file. Bots do use it to guess passwords, though. Turn on multi-factor authentication, limit login attempts and, if only a few people use the admin, allow it only from selected IP addresses. Turn off /xmlrpc.php if no mobile app or other service uses it.

Is it enough to delete the exposed file?

No. Deleting it stops further downloads, but copies someone already has do not go away. Treat every password and key the file contained as compromised and replace them. Only then does cleaning the repository history make sense.

The check found nothing. Is my website fine?

It only means the server did not serve any of the tested paths. Check whether some paths are marked as not verified or access denied because of a firewall. Files with other names, applications in subdirectories and vulnerabilities in the application itself are outside the scope of this check.

Will the server administrator see the check?

Yes. About 60 GET requests appear in the access log with the identifier TunaSec-Security-Scanner/1.0, including random addresses containing tunasec-. We send at most ten at a time and read only the start of each response, so the check does not put a noticeable load on a typical website. Only check websites you manage or have permission to test.

Is it a problem that robots.txt shows where the admin is?

robots.txt is a request to search engines, not protection. It is public, and attackers are among the first to read it. Do not list addresses there that should stay hidden. Protect anything that should not be public with a login, or keep it off the server entirely.

What is security.txt for?

The /.well-known/security.txt file, defined in RFC 9116, tells people where to report vulnerabilities they find. The Contact and Expires fields are required. It helps a security researcher's report reach the right person instead of getting lost in a general inbox.

Want to know what else an attacker could find?

The file check covers only the most common deployment mistakes. Tell us which website it is, and we will discuss how to test it more thoroughly.

Contact us

In a penetration test, we also look for files with other names and for weaknesses in login, APIs and infrastructure, and we verify how far an attacker could actually get.

Penetration testing