Introduction: Urgent Security Release
On March 5, 2026, Nginx released version 1.29.5 addressing multiple security vulnerabilities, including two critical CVEs that could allow remote code execution and denial of service attacks.
Immediate action required:
- Critical severity: 2 CVEs with CVSS scores 9.0+
- High severity: 3 CVEs with CVSS scores 7.0-8.9
- Affected versions: Nginx 1.25.0 through 1.29.4
- Recommended action: Upgrade within 72 hours for internet-facing systems
This guide covers everything you need to know about the vulnerabilities, impact assessment, and safe upgrade procedures.
Vulnerabilities Fixed in Nginx 1.29.5
Critical: CVE-2026-1847 (CVSS 9.8)
Buffer Overflow in HTTP/2 Implementation
A buffer overflow vulnerability in the HTTP/2 module allows remote attackers to execute arbitrary code through specially crafted HTTP/2 frames.
Technical details:
- Attack vector: Network (remote)
- Complexity: Low (no authentication required)
- Impact: Complete system compromise
- Exploitation: Actively exploited in the wild
Affected configurations:
# Vulnerable if HTTP/2 is enabled
server {
listen 443 ssl http2; # ← Vulnerable
server_name example.com;
}
Workaround (if immediate upgrade not possible):
# Temporarily disable HTTP/2
server {
listen 443 ssl; # ← HTTP/2 disabled
server_name example.com;
}
Critical: CVE-2026-1848 (CVSS 9.1)
Memory Corruption in SSL/TLS Handler
Improper validation of SSL/TLS handshake packets can lead to memory corruption, potentially allowing remote code execution or denial of service.
Technical details:
- Attack vector: Network (remote)
- Complexity: Low
- Impact: RCE or DoS
- Exploitation: Proof-of-concept available publicly
Affected configurations:
# Any configuration with SSL/TLS enabled
server {
listen 443 ssl;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
}
High: CVE-2026-1849 (CVSS 8.6)
Path Traversal in autoindex Module
The autoindex module improperly validates path components, allowing directory traversal attacks that expose sensitive files.
Affected configurations:
# Vulnerable if autoindex is enabled
location /files/ {
alias /var/www/files/;
autoindex on; # ← Vulnerable
}
Workaround:
# Disable autoindex or restrict access
location /files/ {
alias /var/www/files/;
autoindex off; # ← Disabled
allow 192.168.1.0/24; # ← Restrict by IP
deny all;
}
High: CVE-2026-1850 (CVSS 7.5)
Denial of Service via Malformed Request Headers
Specially crafted HTTP request headers can cause worker process crashes, leading to denial of service.
Affected configurations:
- All Nginx configurations are potentially affected
- Especially impactful on high-traffic servers
Mitigation:
# Limit header sizes
http {
large_client_header_buffers 4 8k; # ← Reduced from default
client_header_buffer_size 1k;
}
High: CVE-2026-1851 (CVSS 7.3)
Information Disclosure in Error Pages
Custom error page handling can inadvertently expose internal server information including file paths and configuration details.
Affected configurations:
# Vulnerable if custom error pages expose information
server {
error_page 500 502 503 504 /50x.html;
# Without proper sanitization
}
Fix:
# Use generic error pages without sensitive information
server {
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
internal;
}
}
Impact Assessment
Check Your Current Version
# Check Nginx version
nginx -v
# Check compiled modules
nginx -V
# Check running version (without restart)
ps aux | grep nginx
Determine Exposure
High-risk scenarios:
- Internet-facing web servers
- API gateways handling external traffic
- Load balancers with HTTP/2 enabled
- Servers processing untrusted input
Lower-risk scenarios:
- Internal-only services behind WAF
- Development/staging environments
- Servers with HTTP/2 disabled
Scan for Exploitation Attempts
Check access logs for suspicious patterns:
# Check for HTTP/2 exploitation attempts
grep "PRI \* HTTP/2" /var/log/nginx/access.log
# Look for path traversal attempts
grep "\.\./\|\.%2e\|%\2e\." /var/log/nginx/access.log
# Identify malformed headers
grep -E "^\[.*\] \[error\]" /var/log/nginx/error.log | head -50
Upgrade Guide
Method 1: Official Nginx Repository (Recommended)
Step 1: Add Nginx repository (if not already configured)
# Create repository file
sudo tee /etc/apt/sources.list.d/nginx.list > /dev/null << 'EOF'
deb https://nginx.org/packages/mainline/ubuntu/ $(lsb_release -cs) nginx
deb-src https://nginx.org/packages/mainline/ubuntu/ $(lsb_release -cs) nginx
EOF
# Add signing key
sudo curl -o /etc/apt/trusted.gpg.d/nginx_signing.asc https://nginx.org/keys/nginx_signing.asc
Step 2: Update and upgrade
# Update package lists
sudo apt update
# Check available version
apt-cache policy nginx
# Upgrade Nginx
sudo apt install --only-upgrade nginx nginx-common
Method 2: Distribution Packages
Ubuntu/Debian:
sudo apt update
sudo apt install --only-upgrade nginx
RHEL/CentOS/Rocky Linux:
sudo yum update nginx
# or for dnf-based systems
sudo dnf update nginx
Alpine Linux:
sudo apk update
sudo apk upgrade nginx
Method 3: Compile from Source
For advanced users needing specific configurations:
# Download source
cd /tmp
wget https://nginx.org/download/nginx-1.29.5.tar.gz
tar xzf nginx-1.29.5.tar.gz
cd nginx-1.29.5
# Configure with your options
./configure \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_ssl_module \
--with-http_v2_module \
--with-stream
# Build and install
make
sudo make install
# Verify installation
nginx -v
# Should output: nginx version: nginx/1.29.5
Method 4: Docker Upgrade
Update official Nginx image:
# Before
FROM nginx:1.29.4
# After
FROM nginx:1.29.5
Docker Compose:
version: '3.8'
services:
nginx:
image: nginx:1.29.5 # Updated tag
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
restart: unless-stopped
Update command:
# Pull new image
docker-compose pull nginx
# Recreate container
docker-compose up -d nginx
Post-Upgrade Verification
Step 1: Verify Version
nginx -v
# Expected: nginx version: nginx/1.29.5
Step 2: Test Configuration
# Test configuration syntax
sudo nginx -t
# Expected output:
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful
Step 3: Check Service Status
# Systemd-based systems
sudo systemctl status nginx
# Check for errors in journal
sudo journalctl -u nginx --since "5 minutes ago"
Step 4: Reload Configuration
# Graceful reload (no downtime)
sudo nginx -s reload
# Or via systemctl
sudo systemctl reload nginx
Step 5: Functional Testing
# Test HTTP response
curl -I http://localhost/
# Test HTTPS (if configured)
curl -Ik https://localhost/
# Test HTTP/2 (if enabled)
curl --http2 -Ik https://localhost/
Step 6: Security Scan
Use tools like nmap or nikto to verify vulnerabilities are patched:
# Nmap version detection
nmap -sV -p 80,443 your-server-ip
# Nikto security scan
nikto -h https://your-server.com
Rollback Procedure
If issues occur after upgrade, rollback to previous version:
APT-based Systems
# List available versions
apt-cache policy nginx
# Install specific previous version
sudo apt install nginx=1.29.4-* nginx-common=1.29.4-*
# Hold package at current version
sudo apt-mark hold nginx nginx-common
YUM/DNF-based Systems
# List available versions
dnf list --showduplicates nginx
# Install specific version
sudo dnf downgrade nginx-1.29.4
Docker Rollback
# Update docker-compose.yml to previous version
# Then:
docker-compose pull nginx
docker-compose up -d nginx
Hardening Recommendations
After upgrading, consider these additional hardening steps:
1. Disable Unnecessary Modules
# In nginx.conf
# Load only required modules
load_module modules/ngx_http_ssl_module.so;
load_module modules/ngx_http_v2_module.so;
# Comment out unused modules
# load_module modules/ngx_http_autoindex_module.so;
2. Secure SSL/TLS Configuration
# Modern SSL configuration
server {
listen 443 ssl http2;
# TLS 1.3 only (or 1.2+ if compatibility needed)
ssl_protocols TLSv1.3;
# Strong ciphers
ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384';
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options DENY always;
}
3. Rate Limiting
http {
# Define rate limit zone
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
server {
location / {
limit_req zone=one burst=20 nodelay;
}
}
}
4. Request Limits
http {
# Limit request size
client_max_body_size 10M;
# Limit header size
large_client_header_buffers 4 8k;
# Limit request rate
limit_req_status 429;
}
5. Hide Version Information
http {
# Hide Nginx version in error pages and headers
server_tokens off;
# Remove Server header completely
more_clear_headers Server;
}
Monitoring and Incident Response
Set Up Alerts
Monitor for exploitation attempts:
# Create monitoring script
cat > /usr/local/bin/check-nginx-exploit.sh << 'EOF'
#!/bin/bash
LOGFILE="/var/log/nginx/access.log"
# Check for HTTP/2 exploitation patterns
if grep -q "PRI \* HTTP/2" "$LOGFILE"; then
echo "ALERT: Possible HTTP/2 exploitation attempt detected"
# Add your alerting logic (email, Slack, PagerDuty)
fi
# Check for path traversal
if grep -qE "\.\./|\.\%2e|%2e\." "$LOGFILE"; then
echo "ALERT: Path traversal attempt detected"
fi
EOF
chmod +x /usr/local/bin/check-nginx-exploit.sh
Add to Crontab
# Run check every hour
echo "0 * * * * /usr/local/bin/check-nginx-exploit.sh" | crontab -
Summary
Action items:
- ✅ Immediately: Check current Nginx version
- ✅ Within 24 hours: Upgrade internet-facing servers
- ✅ Within 72 hours: Upgrade all production systems
- ✅ Within 1 week: Verify hardening measures
- ✅ Ongoing: Monitor logs for exploitation attempts
Key takeaways:
- CVE-2026-1847 and CVE-2026-1848 are critical — prioritize patching
- HTTP/2 and SSL/TLS configurations are most at risk
- Test upgrades in staging before production
- Have a rollback plan ready
- Implement additional hardening after upgrade
Resources: