I have an up-to-date Wordpress install, and I've tried to do due diligence when it comes to security. However I'm having a recurring problem.

I've put my config at the level above my install location.

However every so often something writes a new wp-config.php to the install location, filled with someone's details.

I've analysed my Apache access logs and I'm seeing this:

[IP removed] - - [22/Nov/2019:17:45:06 +0100] "POST /wordpress//wp-admin/setup-config.php?step=2 HTTP/1.1" 200 1116 "-" "python-requests/2.9.1"
[IP removed] - - [22/Nov/2019:17:45:09 +0100] "POST /wordpress//wp-admin/install.php?step=2 HTTP/1.1" 302 368 "-" "python-requests/2.9.1"
[IP removed] - - [22/Nov/2019:17:45:09 +0100] "GET /wordpress/wp-admin/setup-config.php HTTP/1.1" 200 1487 "-" "python-requests/2.9.1"
[IP removed] - - [22/Nov/2019:17:45:10 +0100] "GET /wordpress//wp-login.php HTTP/1.1" 302 332 "-" "Python-urllib/2.7"
[IP removed] - - [22/Nov/2019:17:45:11 +0100] "GET /wordpress/wp-admin/setup-config.php HTTP/1.1" 200 2791 "-" "Python-urllib/2.7"

I don't know for sure but I suspect that whatever they've managed to POST to the install stage has resulted in Wordpress creating a new config. This doesn't appear to achieve anything tangible for the attacker since they don't have valid credentials, a database or ability to create one, etc etc, but it does put in place a config that breaks the site, directing all access to the installer page.

The config produced is along the lines of this:

 * The base configuration for WordPress
 * The wp-config.php creation script uses this file during the
 * installation. You don't have to use the web site, you can
 * copy this file to "wp-config.php" and fill in the values.
 * This file contains the following configurations:
 * * MySQL settings
 * * Secret keys
 * * Database table prefix
 * @link https://codex.wordpress.org/Editing_wp-config.php
 * @package WordPress

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', '[removed]' );

/** MySQL database username */
define( 'DB_USER', '[removed]' );

/** MySQL database password */
define( 'DB_PASSWORD', '[removed]' );

/** MySQL hostname */
define( 'DB_HOST', 'remotemysql.com' );


I can probably prevent reoccurrence by setting up rules to forbid access to the installer, but surely WP shouldn't be allowing this, and I can't find anything else on the subject.

Am I missing anything in terms of either how this is happening, or what might have been gained as a result?

Edit: it seems like this needs some clarification. I believe that this is WP being induced to write a new config file to the main directory, as it would do if being newly installed. It is not modification of my config at the higher level. It does not appear to be a broader level of compromise.

As the site is non-critical at present, I've started logging request details (POST params etc) to the filesystem and we'll see what I get next time this happens, which is roughly daily.

5 Answers 5


I would do the following things -

1) Check if any malicious content lives on the site. You can use free tools like - https://sitecheck.sucuri.net/

2) Change folder permission of your Wordpress installation to 755 if it's not set to that already. Also change the wp-config.php file permission to 755 to be on the safe side.

3) You can also try to protect wp-config.php file by using the following rule in your .htaccess file. You have to put it at the bottom of the file; after all other rules

<files wp-config.php>
order allow,deny
deny from all
  • I already use Sucuri, and it reports all is well. There is no wp-config (except in the directory above) until the attack generates one, and htaccess won't prevent creation of it, only serving it. Nov 22, 2019 at 20:50

You can move your config file up one directory and should check the file permissions to only allow you, the owner to edit it. If you have access to your .htaccess file, you can add the following to it to prevent access.

# protect wpconfig.php 
<files wp-config.php> 
  order allow,deny 
  deny from all 

https://wordpress.org/support/topic/permission-for-wp-config-php/ https://www.webhostinghero.com/how-to-protect-your-wp-config-php-file-in-wordpress/ https://www.malcare.com/blog/how-to-secure-your-wordpress-site-with-wp-config-php/

  • 1
    Not only would I do that I would go through your user table. Remove any unnecessary admin level users and enforce a change for all passwords. Nov 22, 2019 at 19:54
  • It already is up a directory, and thus inaccessible. The proper config isn't compromised/overwritten; it's eclipsed by one created in the main WP directory. Nov 22, 2019 at 20:46
  • I've also looked through users, content, recently modified files in the filesystem, audit logs etc and found nothing, so I'm kind of working on the basis that this is overall a failed attack. I just don't know how the config is being written - whether by a WP exploit or some other vector. Nov 22, 2019 at 20:55
  • 1
    have you tried also adding the files directive for install.php?
    – C0c0b33f
    Nov 22, 2019 at 22:00
  • Sort of - currently I'm seeing whether any write occurs if I simply remove install.php and setup-config.php, just to confirm that it's not being added by other means. Nov 23, 2019 at 5:51

Scrub the site and restore from backup.

If an attacker can write PHP code, you're system is 100% compromised and needs to be scrubbed. You cannot verify that the attack is over. You cannot figure out what is useful to the attackers or how they do it. They can execute arbitrary code. In other words, you don't own that instance anymore - they do. You still own the domain and hopefully you have access to your data. You should backup your data, and re-install the site to a new server.

A great way to do this is use any basic backup system, but not a FULL backup system. For instance, doing an XML export will lose your monkey, but doing a backup with something like "Duplicator" will simply carry the infection to the new instance.

  • This would be true if the attacker could write arbitrary code. I haven't seen any evidence of this. I think they can induce WP to write its own config file with a set of parameters - effectively a product behaviour but under inappropriate circumstances. Nov 23, 2019 at 5:49
  • That doesn't make sense to me, but it's possible. First of all, wp-config.php IS a PHP file. There aren't any normal WordPress functions that write into it. So whatever mechanism they are using to manipulate the config file is arbitrary. In other words, how can they write to wp-config.php? That's gonna be some kind of hostile software. If you can find it, you won't be able to tell if it's written itself somewhere else, or if it's the only version. Good luck!
    – John Dee
    Nov 23, 2019 at 15:43
  • It was Wordpress, just not the same Wordpress! wordpress.stackexchange.com/a/353181/178765 Nov 23, 2019 at 15:57

I've had a similar problem with a client that has multiple WP and non-WP installation on a shared server. The wp-config file gets some inserted code, and random PHP files are placed, along with inserted code in various (and added) index.php.

I have reset all credentials (hosting, database, admin, etc) with very strong passwords. I have changed permissions on the files (some of the changed files have 'execute' added) to no avail. And the dates of the files don't change when they are modified, so harder to sense.

I've written a file hash checker that compares all file's hashes in a separate table. That alerts me to the problem reoccuring, but I haven't found the infection point yet. And I've looked at just about all of the usual suspects. (Since I haven't found the culprit yet, I obviously haven't looked at the 'right' suspect yet.)

And I have installed two different security plugins on all WP sites; still being attacked. (Luckily, the attack inserts code that doesn't work properly, since the inserted code depends on a specific value in the wp-options table. But it is irritating....) And protected the wp-config file with an htaccess rule; that didn't block it either.

I have noticed that the wp-posts table has some inserted records, so you might look there. I haven't seen anything in the wp-options table yet.

So, looking at every php file for inserted code; look for files with the 'execute' permission set; changing all credentials (hosting, ftp, database, master database, admin); looking for hidden users in wp-users table; look for modified plugins (delete manually and reinstall, which will hopefully save settings); same with themes; and hashing everything are some ideas.

But will be following this, as I haven't got a full solution to either of our problems, but hoping my experiences will help.


I found this resource, which may give you additional protection ideas: https://www.owasp.org/index.php/OWASP_Wordpress_Security_Implementation_Guideline . Many of the suggestions there might be appropriate. YMMV.

And you might consider removing the install.php file - it is not needed after installation. Not sure if it is put back on a WP version update.

  • I'm not sure yours is entirely the same - if you've got DB writes and code insertion then that suggests a broader level of compromise. I think mine is an attacker managing to induce WP to produce its own file. However there's some good security advice in your post. I've started logging the POST parameters made to my suspicious files and now I'll wait until it happens again to try and understand it better. Nov 23, 2019 at 12:09

This turned out to be really, really stupid.

Due to a mistake in the original commissioning process, there was a copy of the Wordpress install within the site, i.e. /wordpress, never set up. This is the sort of thing that would happen if you unpacked the install to the wrong level and then copied it upwards rather than moving it.

In retrospect, the logs were clearly referring to this as the request, but I missed it, thinking that it was filesystem-relative.

The attack speculatively hit this other install with a set of installation parameters, which then produced a config at the level above. This broke the proper site. However, fortunately, subsequent attempts to access the bad site also failed, because for whatever reason it produces a redirect loop. Therefore nothing was achieved.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.