Securing your web server is crucial to protect against various web vulnerabilities. Adding security headers to your Nginx configuration is one effective way to enhance security. Here are some recommended security headers and their settings:

  • Strict-Transport-Security (HSTS): Purpose: Enforces the use of HTTPS for the specified duration, protecting against man-in-the-middle attacks. Configuration:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
  • Content-Security-Policy (CSP): Purpose: Controls the sources from which your site can load content, reducing the risk of XSS attacks. Configuration (adjust as needed for your site’s requirements):
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self';" always;

Another example of Configuration: if is necessary you can add multiple domains on this header just keeping the space between them, like here: *.domain.com *.domain2.com

more_set_headers "Content-Security-Policy default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.domain.com; style-src-elem 'self' 'unsafe-inline' 'unsafe-eval' *.domain.com; font-src 'self' 'unsafe-inline' 'unsafe-eval' *.domain.com; script-src-elem 'self' 'unsafe-inline' 'unsafe-eval' *.domain.com; img-src 'self' 'self' 'unsafe-inline' 'unsafe-eval' *.domain.com; connect-src 'self' 'unsafe-inline' *.domain.com; frame-src 'self' 'unsafe-inline' *.domain.com; manifest-src 'self' 'unsafe-inline'; form-action 'self' 'unsafe-inline'; frame-ancestors 'self'; upgrade-insecure-requests"; 
  • X-Content-Type-Options: Purpose: Prevents browsers from interpreting files as a different MIME type than declared by the server, reducing the risk of MIME-based attacks. Configuration:
add_header X-Content-Type-Options "nosniff" always;
  • X-Frame-Options: Purpose: Prevents your site from being embedded within an iframe, reducing the risk of clickjacking attacks. Configuration:
add_header X-Frame-Options "SAMEORIGIN" always;
  • X-XSS-Protection: Purpose: Enables the browser’s XSS protection mechanism. Configuration:
add_header X-XSS-Protection "1; mode=block" always;
  • Referrer-Policy: Purpose: Controls how much information is included in the Referer header when navigating from one page to another. Configuration:
add_header Referrer-Policy "no-referrer-when-downgrade" always;
  • Feature-Policy: Purpose: Controls which web platform features are allowed or disallowed on a page. Configuration:
add_header Feature-Policy "geolocation 'self'; microphone 'self'; camera 'self'" always;

By implementing these security headers, you create layers of defense against various web vulnerabilities, including unauthorized data access, injection attacks, and privacy issues. These headers contribute to a more secure web environment, protecting both your site and its users from potential threats and attacks.

Remember to adjust these settings based on your specific requirements and the needs of your web application. Additionally, always test thoroughly after making changes to ensure that your website functions correctly with the added security headers.

Sample of Configuration, in the example below I am using an additional module more_set_headers to include new headers, but you can use the default add_header.

    server {
        listen        8081;
        server_tokens off;
        
        more_set_headers    "Server";
        more_set_headers    "X-Content-Type-Options nosniff";
        more_set_headers    "Strict-Transport-Security max-age=31536000; includeSubDomains; preload";
        more_set_headers    "Content-Security-Policy default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.domain.com; style-src-elem 'self' 'unsafe-inline' 'unsafe-eval' *.domain.com; font-src 'self' 'unsafe-inline' 'unsafe-eval' *.domain.com; script-src-elem 'self' 'unsafe-inline' 'unsafe-eval' *.domain.com; img-src 'self' 'self' 'unsafe-inline' 'unsafe-eval' *.domain.com; connect-src 'self' 'unsafe-inline' *.domain.com; frame-src 'self' 'unsafe-inline' *.domain.com; manifest-src 'self' 'unsafe-inline'; form-action 'self' 'unsafe-inline'; frame-ancestors 'self'; upgrade-insecure-requests";        
        
        location / {
            root /usr/share/nginx/html;
            try_files $uri /index.html;

            more_set_headers "Pragma no-cache";
            more_set_headers "Cache-Control max-age=0, no-cache";
        }

        location /assets/ {
           more_set_headers "Cache-Control public max-age=604800";
        }
    }

Links: