How to Harden Nginx: Hide Version, Block Sensitive Files, and Stop Host Header Attacks

This guide walks you through securing an Nginx gateway by hiding its version, blocking access to sensitive files and directories, preventing Host header attacks, adding essential security response headers, and providing a complete configuration template with verification steps for enterprise‑grade protection.

Xiao Liu Lab
Xiao Liu Lab
Xiao Liu Lab
How to Harden Nginx: Hide Version, Block Sensitive Files, and Stop Host Header Attacks
Does your website show any of these high‑risk issues? Host header injection: attackers forge the Host header to steal password‑reset links; Sensitive file leakage: .git, .env, backup.zip can be downloaded directly; Directory traversal: accessing /static/../../../etc/passwd; Nginx version exposure: enables attackers to exploit known vulnerabilities.

Don’t rely on a “firewall‑only” approach—Nginx itself can serve as a powerful security gateway with just a few configuration lines.

Zero‑cost hardening

No extra software required

Meets compliance requirements (e.g., GB/T 22239‑2019)

🛡️ Step 1: Hide Identity – Disable Nginx Version Header

Attackers first probe your service version. Exposed version = a direct path to known exploits.

server_tokens off;
✅ Result:
Original header: Server: nginx/1.24.0
After hardening: Server: nginx

🚫 Step 2: Block Entry – Deny Access to Sensitive Files and Directories

Many data leaks occur because a .env or .git file is publicly downloadable. Add the following global protection (recommended in the http block):

# Deny hidden files (starting with .)
location ~ /\.{
    deny all;
    return 404;
}
# Deny specific sensitive files
location ~* \.(env|git|svn|htaccess|htpasswd|bak|log|sql|zip|tar\.gz)$ {
    deny all;
    return 403;
}
# Deny backup files
location ~* \.bak$ {
    deny all;
    return 403;
}
# Deny directory traversal (explicit hardening)
location ~ \./\./ {
    deny all;
    return 403;
}
# Explanation:
~  = regex match
~* = case‑insensitive regex
deny all = immediately reject the request without returning file content

🌐 Step 3: Lock Identity – Prevent Host Header Attacks (Critical!)

A Host header attack occurs when Nginx is configured with a permissive server_name (e.g., server_name _; or no default reject). An attacker can send:

GET /password-reset HTTP/1.1
Host: attacker.com

If backend code uses the Host header to generate reset links (e.g., https://attacker.com/reset?token=xxx), the attacker can steal credentials.

Security Configuration Plan

Set a default‑reject server block (place it first):

server {
    listen 80 default_server;
    listen 443 ssl default_server;
    server_name _ "";
    return 403;
}

Specify allowed domain names in your business server block:

server {
    listen 80;
    server_name www.yourdomain.com yourdomain.com;
    # Your business configuration...
}

(Optional) Validate Host header at the application layer for defense‑in‑depth.

🛠️ Step 4: Add Security Response Headers (Browser Hardening)

add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https:" always;
Explanation:
X-Frame-Options: DENY – prevents clickjacking
X-Content-Type-Options: nosniff – prevents MIME sniffing
always – ensures error pages also carry these headers

🧪 Verify Effectiveness

1. Check version hiding

curl -I http://your-domain.com

→ Ensure the Server field does not contain a version number.

2. Test sensitive file access

curl -I http://your-domain.com/.env

→ Should return 403 or 404, not 200.

3. Test Host header attack

curl -H "Host: evil.com" http://your-server-ip/

→ Should return 403, not the business page.

📋 Complete Security Configuration Template (Save for Reference)

# /etc/nginx/nginx.conf or site config
# Hide version
server_tokens off;

# Default reject server (place at the top!)
server {
    listen 80 default_server;
    listen 443 ssl default_server;
    server_name _ "";
    return 403;
}

# Business server
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    # Security response headers
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "DENY" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https:" always;

    # Sensitive file protection (can be placed in http block globally)
    location ~ /\.{
        deny all;
        return 404;
    }
    location ~* \.(env|git|bak|log|sql|zip)$ {
        deny all;
        return 403;
    }

    # Your business locations
    location / {
        proxy_pass http://backend;
    }
}

🌟 Summary: Four Core Principles of a Secure Gateway

Minimal Exposure – hide version, disable unused modules

Least Privilege – allow only legitimate domains, reject unknown Hosts

Defense in Depth – Nginx + application‑layer validation

Proactive Protection – add security headers, block sensitive paths

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

SecurityNginxweb serverHardening
Xiao Liu Lab
Written by

Xiao Liu Lab

An operations lab passionate about server tinkering 🔬 Sharing automation scripts, high-availability architecture, alert optimization, and incident reviews. Using technology to reduce overtime and experience to avoid major pitfalls. Follow me for easier, more reliable operations!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.