9 Steps for Enhanced WordPress Security

9 Steps for Enhanced WordPress Security

WordPress websites serve as prime hacker targets. In addition to the platform core, the hackers exploit vulnerabilities like backdoors, malware etc in the various plugins available for website protection. While the key measures to WordPress Security are known and illustrated here , listed below are some additional security checks to be incorporated at the file / directory code levels.

Deny automatic execution of all PHP files

All WordPress websites require new content to be uploaded, and hence the upload directory ‘wp-content/uploads’ usually has Write privileges. This leads to significant risk since malicious PHP files can be entered via this route. While the APIs for the admin console in WordPress does not allow such files to be uploaded, a plugin or theme can be compromised to enter unauthorised PHP content to your website. These PHP files could be continuously run on your web server without your knowledge.

In order to remove this threat, it is required that the web server in which your website is hosted, does not serve and allow any PHP files to be executed. This can be done by configuring the following rule in your ‘wp-content/uploads’ directory:

<Directory "/var/www/wp-content/uploads/">

<Files "*.php">

Order Deny,Allow

Deny from All



Limit direct access to PHP files

In some cases, in the PHP files of themes and plugins, the code is split into smaller files which is then included into bigger code chunks. While security validations are done at the larger code levels, checks may not be performed for the smaller pieces of code. The smaller file is defined in another larger file and hence is not called directly, and hence is easy for you to miss. However, this is what a potential hacker would like to exploit. If the necessary security measures are not performed for the smaller function codes, it may result into disclosure of sensitive information. A typical example of this would be the authentication mechanism, where code to collect the credentials could be split up to obtain the required combinations and then called to serve together for an user to log in.

Nowadays, most of the themes and plugins have direct access to PHP files disabled. However there certainly can be exceptions which you should be aware of and deal accordingly. You should blacklist all unauthorised files and retain the PHP directories / files which are trusted to have direct access. When an HTTP request to a blacklisted PHP file is made, you may want to redirect it to display an error or warning text of your choice. With the help of the following configuration, a 404 error code will be shown for request to any PHP file which is out of the known whitelist.

# Restrict access to PHP files from plugin and theme directories

RewriteCond %{REQUEST_URI} !^/wp-content/plugins/file/to/exclude\.php

RewriteCond %{REQUEST_URI} !^/wp-content/plugins/directory/to/exclude/

RewriteRule wp-content/plugins/(.*\.php)$ - [R=404,L]

RewriteCond %{REQUEST_URI} !^/wp-content/themes/file/to/exclude\.php

RewriteCond %{REQUEST_URI} !^/wp-content/themes/directory/to/exclude/

RewriteRule wp-content/themes/(.*\.php)$ - [R=404,L]

Disable editing within the administrative interface

On similar lines as above, you may completely diasable editing of your themes and plugins via the default Editor provided by WordPress. The required work on these PHP files can be done via alternate secure methods (the best suggestion would be Secure File Transfer Protocol (SFTP)). To diabled the Editor, you need to include the following line of code in your ‘wp-config’ file.

define('DISALLOW_FILE_EDIT', true);

Disable creation of global variables

The ‘register_globals’ directive in your PHP environment is a setting which aids global variables for query string parameters or various server identifiers to be created. This is usually a flag which is enabled or disabled accordingly to perform the said corresponding activity. While WordPress 4.2.0 and above versions have disabled this setting by default, it is required to be certain that the setting is turned off. This shall ensure that a hacker does not perform any unauthorised activity by bypassing security validations for direct access (as in the above point), and run direct GET / POST commands to obtain sensitive information. For this, in the master ‘php.ini’ file on your web server, you need to enter the following line of code:

 register_globals = off 

This can also be done via the ‘ht.access’ file (this is located in your website’s root directory), as demonstrated in the given support thread here.

Permanently hide your error logs and turn off reporting

In the ‘wp-config’ file of your WordPress website, there exists a constant called ‘WP_DEBUG’, which when enabled triggers PHP debugging throughout your website. There are two other sister constants of ‘WP_DEBUG’ namely ‘WP_DEBUG_LOG’ and ‘WP_DEBUG_DISPLAY’. The former creates a log of all the PHP errors noted during development or production deployment, as applicable. The latter shows the error messages which were encountered when the debugging activity was triggered.

By default, WordPress sets the ‘WP_DEBUG’flag as ‘FALSE’. However should the system administrators or the development team manually turns this on for authorised requirements, it is absolutely necessary to ensure that this setting is turned off, as shown below. If possible, these constants should be completely removed. Else, it might lead to hackers exploiting the information about probable errors in your website and using it to their advantage.

define( 'WP_DEBUG', false );

The ‘wp-config’ file can also be configured as below to disable reporting of errors in your PHP files.


@ini_set(‘display_errors’, 0);

Arrest user enumeration

As a forerunner for brute-force attacks for obtaining login passwords, user enumeration is another attack aimed at obtaining your login name for your WordPress website. The hackers execute a malicious script on your website which scans for user related data via numerical user IDs. If successully run, the hacker would be able to generate an entire list of usernames / login IDs of all associated users. This attack is possible if your website has published atleast one post or if permalinks are enabled on your website.

In order to counter this kind of attack, you would need to configure the following rule in the ‘ht.access’ file of your website.

RewriteCond %{QUERY_STRING} author=d

RewriteRule ^ /? [L,R=301]

Prevent directory listing

In absence of the ‘index.html’ file in a particular directory of your website, any random visitor trying to access that directory will be able to see the entire contents of that directory. For example, if a newly created directory called ‘metadata’ has this index file missing, any user trying to access your website (say ‘abc.com’) via the following URL in his browser – http://www.abc.com/metadata, will be able to view the full information stored in this directory, without requiring any passwords / keys / tokens for doing so. This concept is known as Directory Listing .

While this is not a default setting of WordPress, websites running on previous versions of Apache HTTP server have this feature enabled. To prevent hacker exploits via this setting, the following would be needed to be configured in the ‘ht.access’ file of your website.

 Options -Indexes

Set directory permissions accurately

There is no leeway of having your directory and file permissions wrongly configured. It is required for your hosting security, being far more critical if you are in a shared hosting environment. The accurate permission modes and schemes can be seen in this WordPress Codex article. Using the file manager in your admin panel or via the iThemes Security plugin, the permissions to be set at a bare minimum are as follows:

  • 755 for directories
  • 644 for files
  • 600 for wp-config.php

Add cryptographic salts

WordPress ‘salts’ are complex scurity keys or lines of characters which are used in encryption of user session cookies. Similar to strong passwords, these security keys makes the attempt of breaking into a website a little harder. There are eight security keys used by WordPress, namely, AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY, AUTH_SALT, SECURE_AUTH_SALT, LOGGED_IN_SALT, and NONCE_SALT. These keys are present in the ‘wp-config’ file of your website as below.

define('AUTH_KEY', 'put your unique phrase here');

define('SECURE_AUTH_KEY', 'put your unique phrase here');

define('LOGGED_IN_KEY', 'put your unique phrase here');

define('NONCE_KEY', 'put your unique phrase here');

define('AUTH_SALT', 'put your unique phrase here');

define('SECURE_AUTH_SALT', 'put your unique phrase here');

define('LOGGED_IN_SALT', 'put your unique phrase here');

define('NONCE_SALT', 'put your unique phrase here');

Using keys created from a key generator like the WordPress SALT generator and copying and pasting it to the config file will perform the required job.

define('AUTH_KEY', 'C?fNVfE;g#*06tu7?ayb:W0s~Dzc}_VTZp+Kh;7JYY.SO1s/-jkHD9(-E!@v86{Q');

define('SECURE_AUTH_KEY', 'Kg9?q=!wGrDPt[1#`|(<kT^_wCc.N@(G^-)%bLj)IL=#=8vdIi9 @Yp2/0{9 ^xs');

define('LOGGED_IN_KEY', 'AWX-tWCjS*5GlN602e[+@{jNA481wzn|L[m`-nq[tTETn!HB;k _}1.{[{=(-/=%');

define('NONCE_KEY', 'ye* ycLPX+o7MtA]1 xVrq`_Bfm+U)s1,6o*jH{TYbA^2~hK`]*6eyZZ/a]PP[Xa');

define('AUTH_SALT', 'n!{-,}i{6H?eK U`:yj^C%D-.o06.?m t==3P#WdS*Ete P}I|<C0Psb:07^hZ|~');

define('SECURE_AUTH_SALT', '2m3KYC,LMg>P,DS2Vy0n+#&.h! $90xucVQlUKYsA05`/tu+bF(BcBt/RMO-lH#H');

define('LOGGED_IN_SALT', 'zN<7UZU+T-+1jz}a=v,QqJWKtL|X*i<2PmiTa^TKE9VK$un? & FJ++paexCR?~/');

define('NONCE_SALT', '`q!s~|c~XAwL)o|As*[Fefh|&8eb<JuQv~A:.UR5u*xPo_YZ}{[S*Gg$&~z3(aI2');

You can also choose to go the manual route and create the keys all by yourself.

Being Proactive is the Key

These 9 tips shall get you gain a lot of security assurance in preventing attacks via these otherwise easily-missed directory and file configurations. While plugins like Wordfence and iThemes Security will readily incorporate these measures, it is a wise idea to be aware of these settings and check them for their accuracy and efficiency, thereby limiting security violations and harmful impacts in cases of unforeseen attacks.

Anushree Sen

Anushree Sen

Anushree has over 6 years of experience in information security management and risk-based advisory services, working with organizations like Deloitte & Adobe. She is a CISA certified professional, with a management degree in Softwares and Systems from Symbiosis International University. Beyond work, Anushree can be seen practicing various dance forms and dreams of being an established choreographer too.
Anushree Sen