You have probably seen the alias directive in Nginx configs. It is a standard way to serve static files from a directory. It is also one of the most common sources of directory traversal vulnerabilities in web infrastructure.

The rule is this: if a location block uses a trailing slash, the corresponding alias must also use a trailing slash. If you mix them, you create a path traversal bug.

The Vulnerability

Here is the misconfigured version:

location /static {
    alias /var/www/app/;
}

Notice: location /static has no trailing slash, but alias /var/www/app/ does.

With this configuration, Nginx translates /static/style.css to /var/www/app/style.css as intended. But it also translates /static../config/database.yml to /var/www/app/../config/database.yml, which resolves to /var/www/config/database.yml.

An attacker who knows (or can guess) the directory structure above the static files directory can read arbitrary files on the filesystem.

The Correct Configuration

There are two safe forms:

# Both with trailing slash (correct)
location /static/ {
    alias /var/www/app/;
}

# Both without trailing slash (also correct)
location /static {
    alias /var/www/app;
}

# Mixed - VULNERABLE
location /static {
    alias /var/www/app/;
}

The rule is simple but easy to violate, especially when copying configuration snippets from documentation or Stack Overflow where the trailing slash is inconsistent.

What an Attacker Can Access

Depending on the application, an attacker exploiting this can read:

  • Application source code and configuration files
  • Database credentials (database.yml, .env, config.json)
  • Private keys and SSL certificates
  • Internal API keys
  • Session secret keys
  • User data in flat file storage

For applications deployed without containerization, /etc/passwd, /etc/shadow, and SSH authorized keys can be readable. For containerized applications, the damage is limited to the container filesystem but that often includes the entire application codebase and secrets mounted as files.

How to Find It in Your Configuration

Run this against your Nginx config directory:

grep -rn "alias" /etc/nginx/ | grep -v "#"

For each alias directive, check whether the location block and the alias path have matching trailing slashes. Look specifically for cases where alias ends in / but the location does not.

Gixy is an open-source static analysis tool for Nginx configurations that catches this automatically:

pip install gixy
gixy /etc/nginx/nginx.conf

Gixy detects the alias traversal pattern and several other common Nginx misconfigurations. Running it in CI on Nginx config changes is a low-effort improvement with real security impact.

The Scale of the Problem

Security researchers scanning the public internet regularly find hundreds of thousands of Nginx instances with this misconfiguration. Entire hosting platforms have been compromised because a default or example configuration contained the vulnerable alias pattern and was deployed without review.

The 2 million records figure is not hypothetical. In 2021, a major cloud hosting provider had this exact configuration serving customer application files. A security researcher discovered it through a combination of the alias traversal plus an application that exposed its internal path structure in error messages.

Beyond Alias: Other Common Nginx Security Issues

While you are auditing:

Open Proxy

# Dangerous - proxies any URL an attacker provides
location / {
    proxy_pass $arg_url;
}

Unprotected Admin Endpoints

# Intending to block admin, but regex is wrong
location ~ /admin {
    allow 10.0.0.0/8;
    deny all;
}
# /anything/admin/anything still matches
# Use: location ^~ /admin/ for exact prefix matching

Missing Security Headers

Most Nginx configurations lack:

add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header Content-Security-Policy "default-src 'self'";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

These do not prevent server compromise but significantly reduce the impact of client-side attacks.

The Audit Checklist

Check Command / Tool
Alias traversal gixy /etc/nginx/nginx.conf
Open ports nmap -sV your-server-ip
TLS config SSL Labs scan or testssl.sh
Security headers securityheaders.com
Directory listing Check for autoindex on in configs
Server version exposure Look for server_tokens off

Bottom Line

The Nginx alias traversal bug is simple enough to explain in two sentences but serious enough to have caused major data breaches. The fix is trivially easy - match your trailing slashes. The audit takes ten minutes with Gixy.

Run the audit on your production Nginx configuration today, not next sprint. The trailing slash is the kind of thing that looks fine in a code review and is invisible until an attacker uses it.