Security Advisory: Duplicate Post WordPress Plugin SQL Injection Vulnerability (CVE-2021-43408)

The AppCheck Research team identified a security flaw within the “Duplicate Post” WordPress plugin. The plugin has been downloaded 155,421 times at the time of writing. This blog post details the finding along with remediation advice.



The “Duplicate Post” WordPress plugin up to and including version 1.1.9 is vulnerable to SQL Injection.

SQL injection vulnerabilities occur when client supplied data is included within an SQL Query insecurely. SQL Injection can typically be exploited to read, modify and delete SQL table data. In many cases it also possible to exploit features of SQL server to execute system commands and/or access the local file system.

You can read more about SQL injection here;

This particular vulnerability can be exploited by any authenticated user who has been granted access to use the Duplicate Post plugin. By default, this is limited to Administrators, however the plugin presents the option to permit access to the Editor, Author, Contributor and Subscriber roles.


Technical Analysis

The vulnerability occurs in the posthander.php file within the cdp_insert_post function (line 512 for version 1.1.9):

function cdp_insert_post($id, $data, $times, $areWePro, $isChild = false, $p_ids = null, $site) {

    // Get WordPress database
    global $wpdb;

    // Create empty array for new id(s) and error(s)
    $results = array('ids' => array(), 'error' => 0, 'counter' => 0);

    // Get Counter value
    $prefix = (($site != -1) ? $wpdb->get_blog_prefix($site) : $wpdb->get_blog_prefix());
    $newestId = $wpdb->get_results("SELECT post_id FROM {$prefix}postmeta WHERE meta_key = '_cdp_origin' AND meta_value = {$id} ORDER BY post_id DESC LIMIT 1", ARRAY_A); // <-- {$id} is controlled by the attacker

The “$id” parameter passed into the function is included within the SQL statement without proper sanitization. This call can be reached via the registered “wp_ajax_cdp_action_handling” WordPress Ajax callback.

Note that the “id” parameter is passed through the “cdp_sanitize_array” function, this applies the sanitize_text_field function recursively to each item within the array which effectively escapes any quote characters in the string. However, the vulnerable code places the tainted value within the SQL statement where an integer is expected, rather than within a quoted string. Therefore, to manipulate the SQL statement the attacker would only need to avoid using quote characters in the injected payload (e.g. using char() functions) but does not need them to perform the injection attack.

The following HTTP request can be used to recreate the vulnerability. In this example the MySQL “sleep” function is used to trigger a measurable time delay of 9 or more seconds. This value can then be changed to a higher or lower value to confirm execution of the injected SQL statement:

POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Length: 229
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: wordpress_3d2361ff3a8f0d..(truncated)
Connection: close




The vendor has released an updated version (1.2.0) to remediate the flaw. This can be downloaded from



19/10/2021 – AppCheck reported the flaw to the vendor

19/10/2021 – Updated released within the hour.



AppCheck would like to thank Copy Delete Posts for resolving this issue so quickly. An amazing turn around by any standard.


Get started with Appcheck

No software to download or install.

Contact us or call us 0113 887 8380

Start your free trial

Your details
IP Addresses

Get in touch

Please enable JavaScript in your browser to complete this form.