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.
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)
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
aliaswith a trailing slash - Prefer
rootoveraliaswhen 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