Duplicator Update Patches Remote Code Execution Flaw

A critical remote code execution (RCE) vulnerability has been patched in the latest release of Duplicator, a WordPress backup and migration plugin with millions of downloads. In their public disclosure of this flaw, Synacktiv detailed its scope and severity, and provided a viable proof of concept exploit for the security community. In this post we’ll take a look at the basics of the vulnerability, what was patched, and what you can do if you think your site’s at risk.

The Vulnerability

Notably, the vulnerable code in this case isn’t present within the Duplicator plugin directory itself. The flaw becomes exposed when using Duplicator to migrate or restore a backed-up copy of a WordPress site.

Backing up a site generates two files which are both necessary to restore the site’s content: an archived .zip file, and the script which unpacks and configures it, installer.php. These files can be moved to a new server and placed in an appropriate directory, then the admin can visit installer.php in their browser to begin the process of restoring the site’s files and database.

Duplicator’s installer.php interface

Once the restore is completed, you’re prompted to log into the new site. On login, a success page is displayed:

Duplicator migration success screen

On this success page, there’s a Final Steps list which reminds users to remove the leftover files from their Duplicator migration. In fact, if they don’t remove these files, a nag message will be displayed in the site’s WordPress dashboard until either the files are removed or Duplicator is uninstalled.

Persistent “nag” message displayed by Duplicator while installer files still exist

These messages are persistent for a good reason: leaving installation scripts available in a web-accessible location can be really dangerous. There’s a history of this sort of thing being exploited in the wild, like the campaign targeting fresh WordPress installations.

In the case of unpatched Duplicator backups, the installer.php script (and generated copies, like installer-backup.php which will be found in a site’s document root after unpacking) introduces an injection vulnerability by failing to sanitize database configuration data submitted by the user, writing the values directly to the newly generated wp-config.php file.

Example of vulnerable code in installer using raw $_POST input

The above chunk of code is assembling a set of regular expressions to identify database connection strings in the site’s previous wp-config.php file, then defining new values for these strings to be replaced with. These new values are the injectable point.

Exploiting this flaw on a vulnerable site is simple. While there are some basic protections in the installer script that will prevent an admin from overwriting an existing wp-config.php file from the installer’s web interface, these can be bypassed by just supplying the POST parameter action_ajax=3, effectively telling the installer that those checks have already passed.

As for crafting the payload string to be supplied, the payload will be inserted predictably into an existing define()call in the config file, like DB_HOST or DB_USER. As long as a single quote can be successfully passed, an attacker has the ability to add any desired code to the affected site’s wp-config.php file. From this point, backdoors can be established and various malicious activity can be performed.

The Patch

Two issues regarding installation security were addressed in the recent patch to Duplicator. Most relevant to the code injection flaw described above, installer.php scripts generated by patched versions of Duplicator now use addslashes() to sanitize the database connection strings input by users. Now, attackers are unable to inject PHP code into these values.

Additionally, when creating Duplicator packages, a new optional setting has been added for users to password-protect their generated installer scripts. This affords users additional security during the install process, as malicious third parties will no longer have access to the script at all. However, this option is concealed by a collapsible menu at first when generating new packages, so users who aren’t aware it’s been added may miss it at first.

Package creation form in the new Duplicator release, with password protection visible.


Although these patches make needed steps towards securing the process of migrating a WordPress site with Duplicator, it can’t be understated that it’s still of critical importance that any installation files are completely removed once they’re no longer needed.

Even though the user-supplied connection strings are now sanitized before being written to a site’s active wp-config.php file–preventing new code from being introduced and executed–the existing values are still getting replaced by this process. This means if a patched but unprotected installer.php file is found, an attacker has the ability to bring down a site just by supplying incorrect database credentials to the installer.


What Do I Need To Do?

At the time of this writing, we have identified a number of malicious actors probing sites for the existence of installer.php and installer-backup.php. If you’ve used Duplicator in the past to migrate a WordPress site, take some time to confirm that any leftover files from the process have been properly removed. Wordfence Premium users will begin receiving alerts from their malware scanner if vulnerable versions of these files are detected on new scans. Additionally, a new rule has been deployed to protect Premium WAF users from exploits of the Remote Code Execution vulnerability discussed above as long as Extended Protection has been enabled. Free users will receive these new rules thirty days from today.

As always, if you believe your site has fallen victim to the successful exploitation of an attack like this or any other, please don’t hesitate to contact our team of experts to discuss a site cleaning or security audit.

Did you enjoy this post? Share it!


  • Hi, In the past I did migration via duplicator plugin for one of my internet marketing blog site. And now found some leftover files but fixed accordingly above. Thank you so much for this valuable post.

  • Well this "patch" is providing a false sense of security if the "fix" was addslashes().

    It has been shown, multiple times, that the addslashes command does NOT protect a database. There are ways to defeat this and in fact a direct quote from PHP itself:

    "The addslashes() is sometimes incorrectly used to try to prevent SQL Injection. Instead, database-specific escaping functions and/or prepared statements should be used."

    Source: https://secure.php.net/manual/en/function.addslashes.php

    That, again, is the programming language official documentation and not some random site. So using addslashes is a total false sense of security. The correct way is:

    1) Do variable binding, or
    2) Use the database escape like mysqli::real_escape_string

    Source: https://secure.php.net/manual/en/mysqli.real-escape-string.php

    So this plugin is not really patched. #FalseSecurity

    • Hi Jeremy! While you're correct that addslashes() is insufficient to protect against SQL injection, this flaw is in fact a remote code execution, not SQLi. The payload isn't passed through to the database, but is written directly to wp-config.php.