Nginx Top 5 Security Considerations + Problems and their Solutions

Gaurav Talele
4 min readMay 25, 2021

Well, Nginx A Linux based fastest web server across the globe. Yes, you heard right. Today we will see the most important security considerations that can make your nginx server more secure and safer.

Nginx is a web server that can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache.

Step 1. Disable Any Unwanted nginx Modules

When you install nginx, it automatically includes many modules. Currently, you cannot choose modules at runtime. To disable certain modules, you need to recompile nginx. We recommend that you disable any modules that are not required as this will minimize the risk of potential attacks by limiting allowed operations

Step 2. Disable nginx server_tokens

By default, the server_tokens directive in nginx displays the nginx version number. It is directly visible in all automatically generated error pages but also present in all HTTP responses in the Server header.

This could lead to information disclosure — an unauthorized user could gain knowledge about the version of nginx that you use. You should disable the server_tokens directive in the nginx configuration file by setting

server_tokens off;

Step 3. Disable Any Unwanted HTTP methods

disable any HTTP methods, which are not going to be utilized and which are not required to be implemented on the web server. If you add the following condition in the location block of the nginx virtual host configuration file, the server will only allow GET, HEAD, and POST methods and will filter out methods such as DELETE and TRACE.

location / { 
limit_except GET HEAD POST { deny all; }
}

Step 4. Set Up and Configure nginx Access and Error Logs

The nginx access and error logs are enabled by default and are located in logs/error.log and logs/access.log respectively. If you want to change the location, you can use the error_log directive in the nginx configuration file. You can also use this directive to specify the logs that will be recorded according to their severity level. For example, a crit severity level will cause nginx to log critical issues and all issues that have a higher severity level than crit. To set the severity level to crit, set the error_log directive as follows:

error_log logs/error.log crit;

You can find a complete list of error_log severity levels in official nginx documentation.

Step 5. Configure Nginx to Include Security Headers

we can harden nginx server by configuring security headers in server block.

X-Frame-Options: we can use the X-Frame-Options HTTP response header to indicate if a browser should be allowed to render a page in a <frame> or an <iframe>. This could prevent clickjacking attacks.

add_header X-Frame-Options "SAMEORIGIN";

Strict-Transport-Security: HTTP Strict Transport Security (HSTS) is a method used by websites to declare that they should only be accessed using a secure connection (HTTPS). If a website declares an HSTS policy, the browser must refuse all HTTP connections and prevent users from accepting insecure SSL certificates.

add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";

Content Security Policy and XSS-Protection: Content Security Policy (CSP) protects your web server against certain types of attacks, including Cross-site Scripting attacks (XSS) and data injection attacks.

add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;add_header X-XSS-Protection "1; mode=block";

Some of the problems and their solutions.

X-Content-Type-Options: The X-Content-Type-Options header is used to prevent some types of MIME-type sniffing techniques.

By applying the ‘nosniff’ variable, you can ensure the browser will render the data as original, and not as any other.

For example, the web server specifies that the content is text/plain. By using this protection, the browser will render the content only as that MIME type, preventing any sniffing attempts.

add_header X-Content-Type-Options "nosniff" always;

X-Frame-Options: it was pretty common to build websites using iframes, a quick way to include headers, footers, and even remote content from other websites.

Today it’s not as common a practice, but some web applications still use it. Unfortunately, a lot of malicious actors use iframes to perform clickjacking attacks and steal sensitive data from users.

add_header X-Frame-Options "DENY" always;

Problem 1) Lets say we need to correlate NGINX logs with application logs to have an end-to-end understanding of a request.

add_header X-Request-ID $request_id;

and to pass it to app server

location / {
proxy_pass http://app_server;
proxy_set_header X-Request-ID $request_id;
access_log /var/log/nginx/access_trace.log trace;
}

Problem 2) Performance (Joke Though…)

we can cache the static content in client side.

location ~* \.(css|js)$ {  
expires 1y;
add_header Cache-Control "public";
}

Problem 3) Need the client source IP address to be correct in the logs of the backend servers.

X-Forwarded-For Header can be implemented whether or not the --with-http_realip_module was specified at compilation, and modifies the format for the access_log directive to include the X-Forwarded-For Header contents.

log_format  main  
'$http_x_forwarded_for - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';

access_log /var/log/nginx/access.log main;

--

--

Gaurav Talele

An ambitious Full Stack evangelist in Angular, Typescript, Spring Boot Node JS, C#, Dot Net Core WEB API, MS SQL, Redis, MongoDB, RabbitMQ, Docker and AWS.