WordPress: Essential Nginx Security Configuration

WordPress is a widely used content management system, making it a common target for attackers. Securing your WordPress site is crucial, and using Nginx with specific configurations can significantly enhance security. Below, I’ll explain several critical Nginx configurations and why each is essential.

Restrict access to wp-config.php

location = /wp-config.php {
    deny all;
    access_log off;
    log_not_found off;
}

Why this is essential:
The wp-config.php file contains sensitive data, including database credentials and security keys. Restricting direct access prevents attackers from easily gaining access to sensitive information.

Restrict access to wp-includes

location ~* ^/wp-includes/.*\.(php|html|htm)$ {
    deny all;
    access_log off;
    log_not_found off;
}

Why this is essential:
The wp-includes folder contains core WordPress files, which generally don’t require direct access from visitors. Restricting these files reduces the attack surface, particularly against malicious scripts or injections.

NOTE: `js` can’t be included since it has to be used in WordPress Admin UI.

Restrict execution of PHP in wp-content/uploads

location ~* ^/wp-content/uploads/.*\.(php|html|htm|js)$ {
    deny all;
    access_log off;
    log_not_found off;
}

Why this is essential:
The uploads directory should only store user-uploaded media. Blocking the execution of scripts prevents attackers from uploading malicious files that could execute harmful code on your server.

Block files from multisite or plugins that create /files/ alias paths

location ~* /(?:uploads|files)/.*\.php$ {
    deny all;
    access_log off;
    log_not_found off;
}

Why this is essential:
Some plugins and WordPress multisite installations may create additional paths such as /files/. Blocking PHP execution from these paths further protects against plugin vulnerabilities or accidental misconfigurations.

Block access to dotfiles like .htaccess, .htpasswd

location ~ /\. {
    deny all;
    access_log off;
    log_not_found off;
}

Why this is essential:
Dotfiles frequently contain sensitive configuration data or security directives. Preventing access ensures sensitive information remains secure.

Deny access to XML-RPC

location = /xmlrpc.php {
    deny all;
    access_log off;
    log_not_found off;
}

Why this is essential:
XML-RPC is a common attack vector used in brute force and denial-of-service (DoS) attacks. If your site doesn’t rely on XML-RPC (common with modern WordPress setups), it’s safer to disable access.

Prevent access to wp-config-sample.php

location ~* wp-config-sample\.php {
    deny all;
}

Why this is essential:
The sample configuration file can reveal details about your WordPress version or configuration practices. Restricting this file prevents accidental exposure of helpful details to attackers.

Deny access to informational files (readme.html, license.txt)

location = /readme.html {
    deny all;
    access_log off;
    log_not_found off;
}

location = /license.txt {
    deny all;
    access_log off;
    log_not_found off;
}

Why this is essential:
These files disclose your exact WordPress version, giving attackers useful details to exploit specific vulnerabilities. Denying access reduces the amount of information available to attackers.

Conclusion

By implementing these configurations in your Nginx server, you significantly strengthen your WordPress site’s security posture, reducing the likelihood of successful attacks.