Web Application Firewall with NAXSI

NAXSI is a free, open-source web application firewall that runs as an Nginx module to protect web applications from common attacks including SQL injection, cross-site scripting, and malicious file uploads. NAXSI works by analyzing HTTP requests and blocking those that match predefined attack patterns. This guide covers compiling Nginx with the NAXSI module, configuring core rule sets, implementing whitelist exceptions, using learning mode for tuning, and monitoring blocked requests.

Table of Contents

System Requirements

NAXSI requires specific build tools and dependencies:

  • GCC compiler and build tools
  • Nginx source code
  • NAXSI source code
  • Development libraries (libpcre, zlib, OpenSSL)
  • Linux kernel with appropriate permissions
  • 2+ GB disk space for compilation

Check system:

uname -r
gcc --version
which nginx

NAXSI Overview

NAXSI (Nginx Anti XSS and SQL Injection) operates using three strategies:

  1. Whitelisting: Explicitly allows known safe requests
  2. Blacklisting: Blocks requests matching known attack patterns
  3. Learning Mode: Logs suspicious requests for later tuning

NAXSI inspects request parameters, headers, and body content for malicious patterns. When a rule matches, the request is either blocked or logged depending on configuration.

Nginx Compilation with NAXSI

Compile Nginx with the NAXSI module for WAF functionality.

Install dependencies:

For Ubuntu/Debian:

sudo apt-get update
sudo apt-get install -y build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev libgd-dev libgeoip-dev wget curl

For CentOS/RHEL:

sudo yum groupinstall -y 'Development Tools'
sudo yum install -y pcre-devel zlib-devel openssl-devel gd-devel geoip-devel

Download Nginx source:

cd /tmp
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar xzf nginx-1.24.0.tar.gz
cd nginx-1.24.0

Download NAXSI source:

cd /tmp
wget https://github.com/nbs-system/naxsi/archive/1.3.tar.gz
tar xzf 1.3.tar.gz

Configure Nginx with NAXSI module:

cd /tmp/nginx-1.24.0
./configure \
  --prefix=/etc/nginx \
  --sbin-path=/usr/sbin/nginx \
  --modules-path=/usr/lib64/nginx/modules \
  --conf-path=/etc/nginx/nginx.conf \
  --error-log-path=/var/log/nginx/error.log \
  --http-log-path=/var/log/nginx/access.log \
  --pid-path=/var/run/nginx.pid \
  --lock-path=/var/run/nginx.lock \
  --with-http_ssl_module \
  --with-http_v2_module \
  --with-http_realip_module \
  --with-http_gzip_static_module \
  --with-http_secure_link_module \
  --with-http_stub_status_module \
  --add-module=/tmp/naxsi-1.3/naxsi_src

Compile Nginx:

make -j$(nproc)

Install compiled Nginx:

sudo make install

Verify installation:

nginx -V
nginx -V 2>&1 | grep naxsi

Create systemd service for Nginx:

sudo nano /etc/systemd/system/nginx.service

Content:

[Unit]
Description=NGINX HTTP with NAXSI WAF
After=network.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl daemon-reload
sudo systemctl enable nginx
sudo systemctl start nginx

Core Configuration

Configure Nginx with NAXSI protection.

Copy NAXSI rules:

sudo mkdir -p /etc/nginx/naxsi-rules
sudo cp /tmp/naxsi-1.3/naxsi_rules/naxsi_core.rules /etc/nginx/naxsi-rules/

Edit Nginx configuration:

sudo nano /etc/nginx/nginx.conf

Add NAXSI configuration:

http {
    # NAXSI
    include /etc/nginx/naxsi-rules/naxsi_core.rules;
    
    # Logging
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    
    server {
        listen 80;
        server_name example.com;
        
        # Enable NAXSI
        SecRulesEnabled;
        
        # Block mode (set to off for learning)
        SecAuditEngine On;
        
        # Log file for violations
        SecAuditLog /var/log/nginx/naxsi_audit.log;
        
        # Learning mode (log only, don't block)
        LearningMode;
        
        location / {
            proxy_pass http://backend;
        }
    }
}

Test configuration:

sudo nginx -t

Reload Nginx:

sudo systemctl reload nginx

Attack Rules

Understand and manage NAXSI's core rules.

View NAXSI core rules:

cat /etc/nginx/naxsi-rules/naxsi_core.rules | head -50

Rules are organized by rule ID and attack type. Common rule IDs:

  • 1000-1999: SQL Injection
  • 2000-2999: Cross-Site Scripting (XSS)
  • 3000-3999: File Upload
  • 4000-4999: Information Disclosure
  • 5000-5999: Other attacks

Example rules:

MainRule id:1001 "str:union" "mz:BODY" "s:8"; // SQL injection - union
MainRule id:1002 "str:or" "mz:BODY" "s:4"; // SQL injection - or
MainRule id:2001 "str:<script" "mz:BODY" "s:8"; // XSS - script tag
MainRule id:2002 "str:javascript:" "mz:BODY" "s:11"; // XSS - javascript

Disable specific rules if causing false positives:

sudo nano /etc/nginx/nginx.conf

Add in server block:

SecRuleRemoveById 1002;
SecRuleRemoveById 2001;

Or disable entire rule groups:

SecRuleRemoveByTag "sql_injection";
SecRuleRemoveByTag "xss";

Whitelist Configuration

Create whitelists for known safe requests.

Create whitelist file:

sudo nano /etc/nginx/naxsi-rules/naxsi_whitelist.rules

Whitelist specific parameters:

# Whitelist form fields that legitimately contain special characters
# Allow 'search' parameter to contain quotes
WhitelistRule id:1001 "mz:ARGS|search" "msg:whitelist search parameter";

# Allow 'comment' parameter for HTML content
WhitelistRule id:2001 "mz:BODY|comment" "msg:whitelist comment parameter";

# Whitelist API endpoints
WhitelistRule id:1000 "mz:URL|/api/users" "msg:whitelist API endpoint";

# Whitelist AJAX POST data
WhitelistRule id:2000 "mz:BODY|json_data" "msg:whitelist JSON data";

Include whitelist in nginx.conf:

include /etc/nginx/naxsi-rules/naxsi_whitelist.rules;

Whitelist by URI:

location /admin/search {
    SecRuleRemoveById 1001;
    SecRuleRemoveById 1002;
}

location /blog/comments {
    SecRuleRemoveById 2001;
}

Reload configuration:

sudo systemctl reload nginx

Learning Mode

Use learning mode to tune NAXSI before blocking attacks.

Enable learning mode:

sudo nano /etc/nginx/nginx.conf

In server block:

server {
    # Learning mode - log violations but don't block
    LearningMode;
    
    SecAuditLog /var/log/nginx/naxsi_learning.log;
}

Monitor logs:

sudo tail -f /var/log/nginx/naxsi_learning.log

Analyze logged violations:

# Count violations by rule ID
sudo grep "id:" /var/log/nginx/naxsi_learning.log | awk '{print $NF}' | sort | uniq -c | sort -rn

# Find most common violations
sudo tail -100 /var/log/nginx/naxsi_learning.log | grep "id:"

Create whitelists based on learning:

# Extract false positives and create whitelist rules
sudo grep "legitimate" /var/log/nginx/naxsi_learning.log | awk -F'id:' '{print $NF}' > /tmp/false-positives.txt

Once satisfied with tuning, disable learning mode:

sudo nano /etc/nginx/nginx.conf

Remove or comment out:

# LearningMode;

Switch to blocking:

SecAuditEngine On;  # Enable blocking

Reload:

sudo systemctl reload nginx

Custom Rules

Create application-specific rules.

Create custom rule file:

sudo nano /etc/nginx/naxsi-rules/naxsi_custom.rules

Example custom rules:

# Block access to sensitive directories
MainRule id:5001 "str:/admin/sensitive" "mz:URL" "s:8" "msg:Block sensitive admin area";

# Block requests with suspicious user agents
MainRule id:5002 "str:sqlmap" "mz:HEADERS|User-Agent" "s:6" "msg:Block sqlmap scanner";
MainRule id:5003 "str:nikto" "mz:HEADERS|User-Agent" "s:5" "msg:Block nikto scanner";

# Block excessive URL encoding
MainRule id:5004 "regex:%[0-9a-f]{2}%[0-9a-f]{2}" "mz:ARGS" "s:6" "msg:Block double URL encoding";

# Block requests from known malicious IPs
MainRule id:5005 "ip:192.0.2.1" "mz:REMOTE_ADDR" "s:10" "msg:Block known malicious IP";

# Block large file uploads
MainRule id:5006 "size:>100000000" "mz:BODY" "s:10" "msg:Block oversized upload";

# Block null bytes in arguments
MainRule id:5007 "str:%00" "mz:ARGS" "s:8" "msg:Block null byte injection";

Include custom rules:

include /etc/nginx/naxsi-rules/naxsi_custom.rules;

Test custom rules:

# Verify rule syntax
sudo nginx -t

# Check for errors
sudo nginx -T | grep -i error

Monitoring Blocked Requests

Monitor and analyze blocked requests.

View recent blocks:

sudo tail -20 /var/log/nginx/naxsi_audit.log

Count blocks by rule:

sudo grep "id:" /var/log/nginx/naxsi_audit.log | awk -F'id:' '{print $NF}' | sort | uniq -c | sort -rn

Find blocks from specific IP:

sudo grep "SOURCE_IP|192.0.2.1" /var/log/nginx/naxsi_audit.log

Analyze patterns:

# Most common blocked parameters
sudo grep "ARGS" /var/log/nginx/naxsi_audit.log | awk '{print $1}' | sort | uniq -c | sort -rn

# Blocks over time
sudo grep "NAXSI:" /var/log/nginx/naxsi_audit.log | cut -d' ' -f1,2 | sort | uniq -c

Create monitoring script:

sudo nano /usr/local/bin/naxsi-monitor.sh

Content:

#!/bin/bash
LOGFILE=/var/log/nginx/naxsi_audit.log
THRESHOLD=10

# Count blocks in last hour
BLOCKS=$(grep "$(date -d '1 hour ago' +'%d/%b/%Y:%H')" $LOGFILE | wc -l)

if [ $BLOCKS -gt $THRESHOLD ]; then
    echo "Alert: $BLOCKS NAXSI blocks detected in last hour"
    # Send email alert
    echo "Detailed blocks:" | mail -s "NAXSI Alert" [email protected]
fi

Schedule monitoring:

sudo crontab -e

Add:

*/5 * * * * /usr/local/bin/naxsi-monitor.sh

Performance Considerations

Optimize NAXSI for production performance.

NAXSI adds processing overhead to each request. Monitor performance:

# Test request latency
ab -n 1000 -c 10 http://example.com/

# Check CPU usage
top -p $(pgrep nginx)

Disable NAXSI in specific locations if not needed:

location /static/ {
    SecRulesDisabled;
}

location /images/ {
    SecRulesDisabled;
}

Use caching to reduce repeated parsing:

proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 1h;
proxy_cache_bypass $http_pragma $http_authorization;

# Add NAXSI before caching to ensure clean requests

Tune rule aggressiveness:

# Reduce rule sensitivity to minimize false positives
SecRuleRemoveById 1002;  # Remove less critical rules

Conclusion

NAXSI provides application-layer protection against common web attacks without requiring application code changes. By following this guide, you've compiled Nginx with the NAXSI module, configured core rules for attack detection, created whitelists for legitimate requests, used learning mode to tune the WAF, implemented custom rules for application-specific threats, and established monitoring for blocked requests. Proper tuning minimizes false positives while maintaining strong security. Whether protecting simple websites or complex applications, NAXSI provides an effective, open-source WAF solution that integrates directly into Nginx.