← News
/PLAYBOOK · 2026-09-02

Nginx Sensitive-File Leak Protection in Practice: Blocking .git and .env

Hands-on Nginx config to block high-risk paths including .git, .env, and backup archives, while preserving .well-known for certificate validation. Includes access-log triage and a post-leak credential-rotation playbook.

Sensitive-file leak protection is the most overlooked piece of web security. Attackers mass-scan /.git/config, /.env, /backup.zip, and similar paths. A hit yields full source or database credentials and often a full takeover. This article gives a complete Nginx sensitive-file deny config, plus verification and post-leak incident response.

Applicable Scenarios

Prerequisites

How It Works

Automated scanners probe these high-risk paths. Hitting any one can be severe:

The defense: deny at the Nginx layer. Even if the file exists, the attacker cannot read it. Return 404 rather than 403 so scanners do not confirm the target exists.

Procedure

1. Block Hidden Directories and VCS Directories

Add the following to the site server block. Use a (?!well-known) negative lookahead to preserve /.well-known/; otherwise Let's Encrypt certificate validation breaks:

location ~ /\.(?!well-known) {
    deny all;
    return 404;
}

2. Block High-Risk Extensions and Backup Files

location ~* \.(env|sql|bak|old|swp|conf|ini|tar|gz|tgz|zip|7z|rar)$ {
    deny all;
    return 404;
}

If the site has a legitimate archive-download flow, change the rule to deny only files under the web root and explicitly allow the download directory:

location ~* ^/downloads/.*\.(zip|tar\.gz)$ {
    allow all;
}

location ~* \.(env|sql|bak|old|swp|conf|ini|tar|tgz|zip|7z|rar)$ {
    deny all;
    return 404;
}

Nginx location regex matches in order. The allow rule must come first.

3. Disable Directory Listing

Confirm autoindex is off so directory structure is not exposed:

autoindex off;

4. Disable PHP Execution in Upload Directories

Hardening extra: do not execute PHP under upload dirs. Cuts off direct use of a dropped WebShell:

location ~* ^/(uploads|files)/.*\.php$ {
    deny all;
}

5. Reload Config

nginx -t && systemctl reload nginx

Verification

Request the following paths in order. Expect 404 on all:

curl -I https://helixcyber.ai/.env
curl -I https://helixcyber.ai/.git/config
curl -I https://helixcyber.ai/db_backup.sql
curl -I https://helixcyber.ai/site.zip

Also verify /.well-known/ is not blocked (certificate renewal depends on it):

curl -I https://helixcyber.ai/.well-known/acme-challenge/test

FAQ

FAQ 1: Blocking .zip breaks legitimate downloads?

Per step 2, use a more precise location to allow the download directory (e.g. /downloads/) and put the allow rule before the deny rule; or restrict the deny rule to paths matching ^(?!/downloads/). Prefer object storage over the web root for business files so you do not false-positive at all.

FAQ 2: Files were already scanned and downloaded. How to recover?

First establish exposure window: search access logs for scan traces: grep -E '\.(env|git|sql|bak)' /var/log/nginx/access.log. Then run a three-step response: ① rotate every leaked credential immediately—database passwords, Redis passwords, third-party API keys, mail auth codes; ② if .git was accessed, treat all history as leaked; scrub sensitive files with BFG Repo-Cleaner and reset every credential; ③ physically delete .env, backup archives, and similar files from the web root. Config is a backstop, not a root fix.

Summary

Sensitive-file leaks are a classic low-cost, high-impact bug: attack cost is near zero; a hit can take over the site. Nginx-layer deny is deploy-once, long-lived, but must be paired with source control—do not publish VCS dirs to production, do not drop backups in the web root, rotate credentials on a schedule. Put the curl checks above on the launch checklist.