Nginx Hardening for WordPress: Complete Security Guide (Step-by-Step)

Table of Contents

If you are running WordPress on Nginx, securing your stack is not optional—it’s essential. By default, both Nginx and WordPress expose multiple endpoints that bots and attackers actively scan, including /wp-json/, /xmlrpc.php, and login pages.

This guide walks you through practical, production-ready techniques to harden Nginx for WordPress. It is written for both technical users and non-technical readers who want to understand what is happening behind the scenes.

Why Nginx Hardening Matters for WordPress

WordPress powers a massive portion of the internet, which makes it a prime target. Without proper hardening, your site may be exposed to:

  • Brute force login attacks
  • REST API abuse
  • XML-RPC amplification attacks
  • File access exploits
  • Information leakage via headers

Nginx acts as your first line of defense. Proper configuration can block attacks before they ever reach PHP or MySQL.

1. Hide Nginx Version and Server Tokens

Attackers often scan for specific server versions to exploit known vulnerabilities.

NGINX
server_tokens off;

This prevents Nginx from exposing its version in headers and error pages.

2. Add Security Headers

Security headers protect users and reduce attack surface.

NGINX
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
add_header Referrer-Policy "no-referrer-when-downgrade";
add_header Content-Security-Policy "default-src 'self' https: data: 'unsafe-inline' 'unsafe-eval'";

These headers help mitigate XSS, clickjacking, and data injection attacks.

3. Protect Sensitive WordPress Files

Block access to critical files that should never be publicly accessible.

NGINX
location ~* /(wp-config.php|readme.html|license.txt) {
    deny all;
}

4. Disable PHP Execution in Uploads Directory

This prevents attackers from executing malicious scripts uploaded via vulnerabilities.

NGINX
location ~* /wp-content/uploads/.*\.php$ {
    deny all;
}

5. Protect wp-login.php (Brute Force Protection)

Limit login attempts to prevent brute-force attacks.

NGINX
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m;

location = /wp-login.php {
    limit_req zone=login_limit burst=10 nodelay;
    include fastcgi_params;
}

6. Disable or Restrict XML-RPC

XML-RPC is commonly abused for DDoS and brute-force attacks.

Option A: Disable Completely

NGINX
location = /xmlrpc.php {
    deny all;
}

Option B: Allow Specific IP

NGINX
location = /xmlrpc.php {
    allow 123.123.123.123;
    deny all;
}

7. Suppress or Restrict /wp-json/ (REST API)

The WordPress REST API is powerful but often abused.

Block Completely

NGINX
location ~* ^/wp-json/ {
    deny all;
}

Allow Only Logged-in Users (via cookies)

NGINX
location ~* ^/wp-json/ {
    if ($http_cookie !~* "wordpress_logged_in") {
        return 403;
    }
}

8. Harden Specific Endpoint (/wp-json/wp/v2/posts)

This endpoint is often targeted for scraping and enumeration.

Rate Limit It

NGINX
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

location = /wp-json/wp/v2/posts {
    limit_req zone=api_limit burst=20 nodelay;
}

Block Bots by User-Agent

NGINX
if ($http_user_agent ~* (curl|wget|python|bot)) {
    return 403;
}

9. Prevent Access to Hidden Files

Block access to dotfiles such as .htaccess or .env.

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

10. Limit Request Size

Prevent large payload attacks.

NGINX
client_max_body_size 32M;

11. Enable Basic Rate Limiting Globally

This helps mitigate abusive traffic.

NGINX
limit_req_zone $binary_remote_addr zone=global_limit:10m rate=20r/s;

server {
    location / {
        limit_req zone=global_limit burst=40 nodelay;
    }
}

12. Disable Directory Listing

NGINX
autoindex off;

13. Secure FastCGI Configuration

NGINX
fastcgi_hide_header X-Powered-By;

Best Practices Summary

  • Disable unused endpoints like XML-RPC
  • Restrict REST API access
  • Use rate limiting for login and APIs
  • Protect sensitive files
  • Hide server information
  • Use security headers

FAQ: Nginx Hardening for WordPress

Is it safe to disable /wp-json/?

Yes, if your site does not rely on the REST API (e.g., no headless frontend or mobile apps). Otherwise, restrict it instead of fully blocking it.

Will blocking XML-RPC break WordPress?

No for most users. Only specific features like remote publishing or some plugins depend on it.

What is the most important Nginx security setting?

There is no single setting, but rate limiting and blocking unnecessary endpoints provide the biggest impact.

Do I still need a firewall if I harden Nginx?

Yes. Nginx is one layer. You should also use a firewall, secure MySQL, and keep WordPress updated.

How often should I review my Nginx config?

At least every few months or after major WordPress/plugin updates.

Conclusion

Hardening Nginx for WordPress is one of the most effective ways to secure your website. By blocking unnecessary endpoints, limiting abuse, and applying proper headers, you significantly reduce your attack surface.

Start with the critical protections like XML-RPC blocking and rate limiting, then gradually implement more advanced controls as needed.

← How Hackers Actually Hack WordPress: Data Extraction & Exploitation Techniques Explained PHP-FPM 8.x Optimization Guide for High Performance WordPress (Ubuntu) →
Share this page
Back to top