Authenticated PHP Object Injection Vulnerability in Business Directory Plugin
We recently started proactively monitoring for evidence of some high risk vulnerabilities when changes are made to WordPress plugins and if we had more customers we could expand the proactive monitoring to more types of vulnerabilities. One of the types of vulnerabilities we are looking for are PHP object injection vulnerabilities since those are likely to be exploited if hackers become aware of them (unlike other types of vulnerabilities that security companies are known to overstate the impact of). Through that we came across an authenticated PHP object injection vulnerability in the plugin Business Directory Plugin.
The plugin makes the function ajax_csv_export() available to anyone logged in to WordPress through WordPress’ AJAX functionality (in the file /includes/admin/csv-export.php):
13 | add_action( 'wp_ajax_wpbdp-csv-export', array( &$this, 'ajax_csv_export' ) ); |
This plugin requires user registration by default for a major piece of its functionality, so it is likely that fair number of the websites using it would allow untrusted individuals to create accounts.
As of version 4.1.14 that function would unserialize the value of the GET or POST input “state”, which can cause PHP object injection:
30 31 32 33 34 35 36 37 | public function ajax_csv_export() { $error = ''; try { if ( !isset( $_REQUEST['state'] ) ) { $export = new WPBDP_CSVExporter( array_merge( $_REQUEST['settings'], array() ) ); } else { $export = WPBDP_CSVExporter::from_state( unserialize( base64_decode( $_REQUEST['state'] ) ) ); |
After we notified the developer of the issue they released version 4.1.14.1, which fixes the vulnerability by replacing the usage of the function unserialize() with json_decode() (and replaces the related usage of the serialize() with json_encode() elsewhere). They also added a restriction to limit access to the function to those logged in as Administrators:
30 31 32 33 34 35 36 37 38 39 40 41 | public function ajax_csv_export() { if ( ! current_user_can( 'administrator' ) ) { exit(); } $error = ''; try { if ( ! isset( $_REQUEST['state'] ) ) { $export = new WPBDP_CSVExporter( array_merge( $_REQUEST['settings'], array() ) ); } else { $state = json_decode( base64_decode( $_REQUEST['state'] ), true ); |
Proof of Concept
With our plugin for testing for PHP object injection installed and activated, visiting the following URL while logged in to WordPress will cause the message “PHP object injection has occurred.” to be shown.
Make sure to replace “[path to WordPress]” with the location of WordPress.
http://[path to WordPress]/wp-admin/admin-ajax.php?action=wpbdp-csv-export&state=TzoyMDoicGhwX29iamVjdF9pbmplY3Rpb24iOjA6e30=
Timeline
- July 31, 2017 – Developer notified.
- August 2, 2017 – Version 4.1.14.1 released, which fixes vulnerability.