How to Prevent PHP Files in WordPress on NGINX Server?

When we run a WordPress site, there are some files in the WP directory that visitors should never access. They exist only for WordPress to perform its routine operations through its server. But due to WordPress’ schema and structure some computer geeks can still gain access to these files. 

All these directories combined are meant to perform separate actions being part of the large application WordPress. 

However, some hackers try to reach these directories by running PHP execution commands and harm the site. These directories need to be protected by denying access to them on the NGINX server; they will still perform their core functions. 

The wp-includes these directories that are by default accessible through PHP execution. The important directories which might get harmed are still open to PHP execution are uploads, themes and plugins. They are there by default and exist in wp-content media, wp-content/themes and wp-content/plugins. They also can be moved somewhere else and so does WP-content directory itself.

We have listed below important directories that you can prevent from getting executed by adding denial commands

Preventing PHP Execution in the Content directory

If you want to prevent your Content Directory you should add the following command to prevent it from getting triggered with PHP execution.

This directory is by default /wp-content, but it can easily be defined to be elsewhere by simply changing the settings the WP_CONTENT_DIR/WP_CONTENT_URL constants, so you need to do the config as it should be.

# Prevent PHP scripts from being executed in the content directory
location ~* /wp-content/.*.php$ { 
         deny all; 
         access_log off; 
         log_not_found off;
}

Preventing PHP Execution in the includes directory

If you want to prevent your Includes Directory you should add the following command to prevent PHP execution.

Please not that the location should always be the same.

# Prevent PHP scripts from being executed in the includes directory
location ~* /wp-includes/.*.php$ {
	deny all;
	access_log off;
	log_not_found off;
}

Preventing PHP Execution in the plugin and theme directories

We all leave the themes and plugins directories without even opening them once or trying to do anything with them and they exist within the content directory the entire time. They can be moved easily. We can define the constant pair  for plugins WP_PLUGIN_DIR/WP_PLUGIN_URL, and also for themes use the function register_theme_directory(). 

However, if you have already moved them elsewhere from the content directory add similar location blocks for both. If you have not just leave this part untouched. 

If the plugins directory is moved from Content Directory dir to e.g. /modules:

location ~* /modules/.*.php$ {
	deny all;
	access_log off;
	log_not_found off;
}

If the theme dir is also moved to somewhere else  e.g. /skins:

location ~* /skins/.*.php$ {
	deny all;
	access_log off;
	log_not_found off;
}

However, if someone is still using the both , you can combine them like we did in the includes directoryp.

Preventing xmlrpc.php from execution

We may not need XML-RPC as we do not most of the time, however, if you use Jetpack or WordPress app you do use it. You can prevent it if you are using it. As we know all the XML-RPC requests are routed through the file xmlrpc.php but you can prevent it.

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

Preventing PHP Execution in the uploads directory on NGINX Server

If you are running Bedrock Setup on NGINX server you can protect your uploads with a single PHP command. In order to protect your uploaded WordPress files you need to add this command line in your Bedrock setup. This will prevent PHP scripts from being executed inside the uploads folder.


# Prevent PHP scripts from being executed inside the uploads folder.
  location ~* /app/uploads/.*.php$ {
    deny all;
  }

  location ~* /bedrock/web/app/uploads/_pda {
       rewrite uploads(/_pda/.*\.\w+)$ "/bedrock/web/index.php?pda_v3_pf=$1" last;
   }
   location ~* /bedrock/web/private {
        rewrite private/([a-zA-Z0-9-_]+)$ "/bedrock/web/index.php?pda_v3_pf=$1&pdav3_rexypo=ymerexy" last;
   }
}

Restart the NGINX server.