NGINX Alias Path Traversal

A subtle misconfiguration in the alias directive can expose your entire filesystem. Learn how it happens and how to prevent it.

Updated: January 2025 6 min read

What is Alias Path Traversal?

Alias path traversal is a vulnerability that occurs when the NGINX alias directive is used with a location that doesn't end with a slash. This allows attackers to escape the intended directory and access files elsewhere on the filesystem.

Why This is Critical

This vulnerability can allow attackers to:

  • Read sensitive configuration files (/etc/passwd, .env, etc.)
  • Access application source code
  • Steal database credentials and API keys
  • Download private SSL certificates

The Root Cause

The alias directive replaces the location prefix with a filesystem path. The vulnerability occurs because NGINX performs simple string replacement without enforcing directory boundaries.

How alias works:
location /files { alias /var/www/static/; }
Request: GET /files/image.jpg
Maps to: /var/www/static//image.jpg → /var/www/static/image.jpg
The vulnerability:
location /files { alias /var/www/static/; }
Request: GET /files../etc/passwd
Maps to: /var/www/static/../etc/passwd/etc/passwd
Without trailing slash in location, "../" escapes the intended directory

Vulnerable Pattern

The classic vulnerable configuration looks like this:

# Location without trailing slash + alias with trailing slash
location /files {
    alias /var/www/static/;
}

# Attack: GET /files../etc/passwd
# NGINX sees: /files + ../etc/passwd
# Resolves to: /var/www/static/../etc/passwd = /var/www/etc/passwd
# With further traversal: /var/www/static/../../etc/passwd = /etc/passwd

The key issue is the missing trailing slash on the location. When the location is /files (no slash), requesting /files../ is valid and the .. becomes part of the path passed to alias.

Regex Location Variant

# Regex location with alias
location ~ /site/(.*) {
    alias /var/www/$1;
}

# Attack: GET /site/../../../etc/passwd
# $1 captures: ../../../etc/passwd
# Resolves to: /etc/passwd

Secure Patterns

Add Trailing Slash to Location

# Both location and alias end with /
location /files/ {
    alias /var/www/static/;
}

# Now /files../ is a 404 (doesn't match /files/)
# Only /files/something matches, which is safe

Use root Instead of alias

# root appends the full location path
location /static/ {
    root /var/www;
}

# Request: GET /static/image.jpg
# Maps to: /var/www/static/image.jpg
# Traversal: GET /static/../etc/passwd
# Maps to: /var/www/static/../etc/passwd (NGINX normalizes this)
# Result: /var/www/etc/passwd (still under /var/www)
When to use root vs alias:
  • root — Appends the location to the path. Safer by default.
  • alias — Replaces the location prefix. Needed when the URL structure differs from filesystem structure.

Restrict Regex Capture Groups

# Restrict what can be captured
location ~ ^/downloads/([a-zA-Z0-9_-]+\.pdf)$ {
    alias /var/www/pdfs/$1;
}

# Only alphanumeric filenames with .pdf extension allowed
# No dots, slashes, or traversal sequences possible

Detecting with Gixy

Gixy automatically detects alias path traversal vulnerabilities:

$ gixy /etc/nginx/nginx.conf

==================== Results ====================

[alias_traversal] Path traversal via misconfigured alias.
  Severity: HIGH
  Description: Using alias in a prefixed location that doesn't
               end with directory separator could lead to path
               traversal vulnerability.
  Pseudo config:
      server {
          location /files {
              alias /var/www/static/;
          }
      }
  File: /etc/nginx/conf.d/static.conf
  Line: 8

==================== Summary ====================
Total issues: 1 (High: 1)

Testing for the Vulnerability

You can test your configuration with curl:

# Test for path traversal
curl -v "https://example.com/files../etc/passwd"

# If vulnerable, you'll see the contents of /etc/passwd
# If secure, you'll get a 404 or 400 error

Common Misconceptions

1. "NGINX normalizes paths"

NGINX does normalize paths, but the normalization happens before matching. When the location is /files without a trailing slash, /files../ is a valid match that doesn't get normalized away.

2. "I'm using a regex, so I'm safe"

Regex locations can be even more dangerous because capture groups can contain anything, including ../ sequences. Always restrict what your capture groups can match.

3. "The alias path doesn't end with /, so it's safe"

Actually, when the alias path doesn't end with a slash, the vulnerability is worse because the traversal starts from a different position. Both cases can be vulnerable.

Prevention Checklist

  • Always end locations using alias with a trailing slash
  • Prefer root over alias when possible
  • Restrict regex capture groups to safe character sets
  • Never allow dots in captured path segments
  • Run Gixy to automatically detect misconfigurations
  • Test your config with path traversal payloads

Further Reading