Configuring NAXSI (WAF)

Configuring NAXSI (WAF)

in my previous post the installation of NGINX and NAXSI was described. After successful installation it is time to start the configuration.

as a first step copy core rules, to Nginx config directory.

Configring NGINX

sudo  /src/naxsi-0.56/naxsi_config/naxsi_core.rules /etc/nginx/

than create your specific config-file

sudo vi /etc/nginx/naxsi.rules

and add the block of code below that defines some basic protection

SecRulesEnabled;
# LearningMode;
DeniedUrl "/RequestDenied";

error_log /var/log/nginx/naxsi_www.error.ch.log;

## Check Naxsi rules
CheckRule "$SQL >= 8" BLOCK;
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 4" BLOCK;
CheckRule "$EVADE >= 4" BLOCK;
CheckRule "$XSS >= 8" BLOCK;

now it is time to configure NGINX to use NAXSI. This will be done in /etc/nginx/nginx.conf.

[...]
[...]
http {
    [...]
    include /etc/nginx/naxsi_core.rules;
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
    [...]
}

Then in the Server Blocks (Virtual Hosts) config (/etc/nginx/sites-available/yourSite) include the naxsi.rules.

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name www.error.ch;

    ssl_certificate /etc/letsencrypt/www.error.ch/fullchain.cer;
    ssl_certificate_key /etc/letsencrypt/www.error.ch/www.error.ch.key;
    include /etc/nginx/snippets/ssl-params.conf;

    location / {
        include /etc/nginx/naxsi.rules;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2368;
    }

    client_max_body_size 50m;
}

After a restart of NGINX the rules are loaded and active.

Testing

the most simple test to see if the WAF is working, is to send a GET request towards the server including some type of SQL Injection.
https://www.error.ch/?TypeId=1 or '1'='1' will do.

the expected result is that the browser will be redirected to https://www.error.ch/RequestDenied as configured in naxsi.rules

False positives

For sure the one or other legitimate request will be blocked. To handle false-positives Naxsi logs need to be analyzed and whitelist rules need to be created. Thanks to nxutli this does not cause us any headaches.

cd /opt
git clone https://github.com/prajal/nxutil.git
cd nxutil
python setup.py install

with the command

python nx_util.py -l /var/log/nginx/naxsi_www.error.ch.log -o -p 1

the logfile gets processed and you'll see an output like the one below.

########### Optimized Rules Suggestion ##################
# total_count:62 (13.57%), peer_count:1 (100.0%) | double quote
BasicRule wl:1001 "mz:BODY";
# total_count:58 (12.69%), peer_count:1 (100.0%) | open square backet ([), possible js
BasicRule wl:1310 "mz:BODY";
# total_count:52 (11.38%), peer_count:1 (100.0%) | backslash
BasicRule wl:1205 "mz:BODY";
# total_count:43 (9.41%), peer_count:1 (100.0%) | https:// scheme
BasicRule wl:1101 "mz:BODY";
# total_count:42 (9.19%), peer_count:1 (100.0%) | simple quote
BasicRule wl:1013 "mz:$BODY_VAR:excerpt";

include this whitelist rules into your /etc/nginx/naxsi.rules and the requests won't be blocked anymore.

managed whitelists

on GitHub you'll also find NAXSI rules provided and maintained by the community.