WordPress Pinterest Automatic plugin (7,000+ sales on Envato Market) fixed a critical vulnerability affecting version 4.14.3 and below that could allow unauthenticated users to take over the website and its database.
Unauthenticated Arbitrary WordPress Options Change
CVSS v3.1: 9.8 (Critical)
In the “wp-pinterest-automatic/pinterest-auto.php” main script, WordPress Pinterest Automatic registers the wp_pinterest_automatic_parse_request
action with the parse_request
hook, i.e., when all query variables for the current request have been parsed:
940 /** 941 * custom request for fetch boards 942 */ 943 function wp_pinterest_automatic_parse_request($wp) { 944 945 // only process requests with "my-plugin=ajax-handler" 946 if (array_key_exists('wp_pinterest_automatic', $wp->query_vars)) { 947 948 if($wp->query_vars['wp_pinterest_automatic'] == 'boards'){ 949 950 require_once('p_core.php'); 951 exit; 952 953 }elseif($wp->query_vars['wp_pinterest_automatic'] == 'settings'){ 954 955 require_once('process_form.php'); 956 exit; ... ... ... 1067 } 1068 add_action('parse_request', 'wp_pinterest_automatic_parse_request');
If the wp_pinterest_automatic
query var is set to settings
, it loads the “process_form.php” script:
<?php /** * Created with Visual Form Builder by 23rd and Walnut * www.visualformbuilder.com * www.23andwalnut.com */ $form = new ProcessForm(); $form->field_rules = array( 'field1'=>'required', 'field3'=>'required', 'field4'=>'required', 'field5'=>'required', 'field6'=>'required' ); $form->validate(); class ProcessForm { public $field_rules; public $error_messages; public $fields; private $error_list; private $is_xhr; function __construct() { $this->error_messages = array( 'required' => 'This field is required', 'email' => 'Please enter a valid email address', 'number' => 'Please enter a numeric value', 'url' => 'Please enter a valid URL', 'pattern' => 'Please correct this value', 'min' => 'Please enter a value larger than $1', 'max' => 'Please enter a value smaller than $1' ); $this->field_rules = array(); $this->error_list = ''; $this->fields = $_POST; $this->is_xhr = $this->xhr(); } function validate() { if (!empty($this->fields)) { //Validate each of the fields foreach ($this->field_rules as $field => $rules) { $rules = explode('|', $rules); foreach ($rules as $rule) { $result = null; if (isset($this->fields[$field])) { $param = false; if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match)) { $rule = $match[1]; $param = $match[2]; } $this->fields[$field] = $this->clean($this->fields[$field]); //if the field is a checkbox group create string if (is_array($this->fields[$field])) $this->fields[$field] = implode(', ', $this->fields[$field]); // Call the function that corresponds to the rule if (!empty($rule)) $result = $this->$rule($this->fields[$field], $param); // Handle errors if ($result === false) $this->set_error($field, $rule); } } } if (empty($this->error_list)) { if ($this->is_xhr) echo json_encode(array('status' => 'success')); $this->process(); } else { if ($this->is_xhr) echo json_encode(array('status' => 'invalid', 'errors' => $this->error_list)); else echo $this->error_list; } } } function process() { foreach($this->fields as $key => $field){ update_option( $key, $field); } if (! is_array($this->fields['wp_pinterest_options'])){ update_option( 'wp_pinterest_options', array()); } } ... ...
Line 44, it assigns the POST
payload to $this->fields
and, in the process
method lines 117-119, it takes every key/value pairs found in it and passes them on to the WordPress update_option
function.
Neither the wp_pinterest_automatic_parse_request
function nor the “process_form.php” script have a capability check to restrict access to that code. They also lack a security nonce.
An unauthenticated user can modify every WordPress options in the database in order, for instance, to create an administrator account or redirect all traffic to an external malicious website among many other possibilities.
Recommendations
Update immediately if you have version 4.14.3 or below installed. If you are using our web application firewall for WordPress, NinjaFirewall WP Edition (free) and NinjaFirewall WP+ Edition (premium), you are protected against this vulnerability.
Timeline
The vulnerability was reported to Envato on August 20, 2021, and a new version 4.14.4 was released on August 23, 2021.
Stay informed about the latest vulnerabilities
- Running WordPress? You can get email notifications about vulnerabilities in the plugins or themes installed on your blog.
- On Twitter: @nintechnet