The WordPress Kali Forms plugin (30,000+ active installations) fixed multiple vulnerabilities. Affected versions are 2.1.0 and below and, to some extend, version 2.1.1 (see Timeline below for more details).
Unauthenticated Arbitrary Post Deletion
In the “kali-forms/Inc/Frontend/class-form-processor.php” script L91-92, the plugin registers the kaliforms_form_delete_uploaded_file
AJAX action to call the “delete_file” function, and makes it accessible to all users, authenticated or not:
add_action('wp_ajax_kaliforms_form_delete_uploaded_file', [$this, 'delete_file']); add_action('wp_ajax_nopriv_kaliforms_form_delete_uploaded_file', [$this, 'delete_file']);
The function is located in the “kali-forms/Inc/Utils/class-filemanager.php” L138:
public function delete_file() { $_POST['id'] = absint(wp_unslash($_POST['id'])); return wp_delete_post($_POST['id'], true); }
It takes the value of $_POST['id']
and calls the wp_delete_post function.
An unauthenticated user can delete every page and post on the blog.
Authenticated Options Change
In the “/kali-forms/Inc/Backend/class-hooks.php” script L63, the plugin registers the kaliforms_update_option_ajax
AJAX action to call the “update_option” function and makes it accessible to authenticated users:
add_action('wp_ajax_kaliforms_update_option_ajax', [$this, 'update_option'] );
The “update_option” function is located in the same script L125:
public function update_option() { if (isset($_POST['args'], $_POST['args']['nonce']) && !wp_verify_nonce(sanitize_key(wp_unslash($_POST['args']['nonce'])), $this->slug . '_nonce')) { wp_die(wp_json_encode([ 'success' => false, 'message' => esc_html__('Denied', 'kaliforms'), ])); } $args = stripslashes_deep($_POST['args']); $args['method'] === 'delete' ? delete_option($this->slug . '_' . $args['option']['key']) : update_option($this->slug . '_' . $args['option']['key'], sanitize_text_field($args['option']['value'])); wp_die(wp_json_encode([ 'success' => true, 'message' => 'ok - updated option: ' . $args['option']['key'] . ' with the value: ' . $args['option']['value'], ])); }
It lacks a capability check and the security nonce can be bypassed because the $_POST['args']['nonce']
input is only checked if it is set.
An authenticated user can change (or delete) the plugin’s settings. For instance, by modifying the SMTP server credentials settings (e.g., kaliforms_smtp_provider
, kaliforms_smtp_host
, kaliforms_smtp_username
, kaliforms_smtp_password
etc), all submitted form data will be redirected to the attacker’s mailbox/SMTP server.
CSRF
Throughout the plugin’s code, security nonces can be bypassed because they are only checked if they are set:
-https://plugins.trac.wordpress.org/browser/kali-forms/tags/2.1.0/Inc/Utils/class-duplicate-post.php#L49
-https://plugins.trac.wordpress.org/browser/kali-forms/tags/2.1.0/Inc/Frontend/class-form-processor.php#L242
-https://plugins.trac.wordpress.org/browser/kali-forms/tags/2.1.0/Inc/Frontend/class-form-processor.php#L655
-https://plugins.trac.wordpress.org/browser/kali-forms/tags/2.1.0/Inc/Backend/class-form-styles.php#L75
-https://plugins.trac.wordpress.org/browser/kali-forms/tags/2.1.0/Inc/Backend/class-plugin-health-checks.php#L216
-https://plugins.trac.wordpress.org/browser/kali-forms/tags/2.1.0/Inc/Backend/class-plugin-review.php#L156
-https://plugins.trac.wordpress.org/browser/kali-forms/tags/2.1.0/Inc/Backend/class-hooks.php#L152
-https://plugins.trac.wordpress.org/browser/kali-forms/tags/2.1.0/Inc/Backend/class-predefined-forms.php#L44
-https://plugins.trac.wordpress.org/browser/kali-forms/tags/2.1.0/Inc/Backend/class-plugin-deactivation.php#L96
-https://plugins.trac.wordpress.org/browser/kali-forms/tags/2.1.0/Inc/Backend/class-notifications.php#L107
Additional Issues
In the “kali-forms/Inc/Backend/class-hooks.php”, the “clear_mail_log” function L150 is loaded by the kaliforms_clear_log
AJAX action L66. There’s no capability check, any authenticated user can delete the plugin’s log.
Timeline
The vulnerabilities were reported to the wordpress.org plugins team on August 7th, 2020 and a new version 2.1.1 was released on August 15th. However, because that version introduced two new vulnerabilities, version 2.1.2 was released on August 17th, 2020.
Recommendations
Upgrade immediately if you have version 2.1.1 or below. 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.
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