WordPress Plugin Security Review: Maspik – Spam blacklist
For our 43nd security review of a WordPress plugin based on the voting of our customers, we reviewed the plugin Maspik – Spam blacklist.
If you are not yet a customer of the service, once you sign up for the service as a paying customer, you can start suggesting and voting on plugins to get security reviews. For those already using the service that haven’t already suggested and voted for plugins to receive a review, you can start doing that here. You can use our tool for doing limited automated security checks of plugins to see if plugins you are using have possible issues that would make them good candidates to get a review. You can also order a review of a plugin separately from our service.
The review was done on version 0.10.6 of Maspik – Spam blacklist. We checked for the following issues during it as part of our standard review:
- Insecure file upload handling (this is the cause of the most exploited type of vulnerability, arbitrary file upload)
- Deserialization of untrusted data
- Security issues with functions accessible through WordPress’ AJAX functionality (those have and continued to be a common source of disclosed vulnerabilities)
- Security issues with functions accessible through WordPress’ REST API (those have started to be a source of disclosed vulnerabilities)
- Persistent cross-site scripting (XSS) vulnerabilities in the frontend portions of the plugin and in the admin portions accessible to users with the Author role or below
- Cross-site request forgery (CSRF) vulnerabilities in the admin portion of the plugin
- SQL injection vulnerabilities (the code that handles requests to the database)
- Reflected cross-site scripting (XSS) vulnerabilities
- Security issues with functions accessible through any of the plugin’s shortcodes
- Security issues with functions accessible through any of the plugin’s blocks
- Security issues with functions accessible through the admin_action action
- Security issues with functions accessible through the admin_init action
- Security issues with functions accessible through the admin_post action
- Security issues with import/export functionality
- Security issues with usage of the is_admin() function
- Security issues with usage of the add_option(), delete_option(), and update_option() functions
- Security issues with usage of the update_user_meta() and wp_update_user() functions
- Security with usage of determine_current_user filter
- Security issues with usage of the wp_set_current_user(), wp_set_auth_cookie() and wc_set_customer_auth_cookie() functions
- Security issues with usage of the reset_password() and wp_set_password() functions
- Security issues with usage of the extract() function
- Lack of IP address validation
- Proper usage of sanitize_callback when using register_setting() to register settings.
- CSV injection
- Host header injection vulnerabilities
- Lack of protection against unintended direct access of PHP files
- Insecure and unwarranted requests to third-party websites
- Any additional possible issues identified by our Plugin Security Checker
Results
We found the plugin contained several vulnerabilities and several places where security could be improved, which are detailed below.
We notified of developer of the issues we found on January 17. They got back to us later that day, stating they were working on things. Yesterday, they released version 0.10.7, which they said fixed all the issues. As part of preparing this post, we found it actually only mostly addresses the issues.
Cross-Site Request Forgery (CSRF)
We found two places where there is a lack of a nonce check to prevent cross-site request forgery (CSRF) from occurring. They occurred with functionality to refresh an API file and when activating a license for the plugin. Those were attempted to be resolved by adding a nonce check before the functionality is run, as can be seen with the code for one of those:
14 15 16 | if ( isset( $_GET['cfas_nonce'] ) && wp_verify_nonce( $_GET['cfas_nonce'], 'cfas_refresh_api_nonce' ) ) { // Nonce is valid, proceed with refreshing API cfas_refresh_api(); |
The other check added doesn’t work, as we have notified the developer of. We will address that issue what went wrong in a follow up post, as this is something we have seen gotten wrong in other plugins as well.
Privilege Escalation and Cross-Site Request Forgery (CSRF)
Functionality to enable usage tracking by the plugin was accessible to anyone logged in to WordPress and lack protection against CSRF. That was resolved by adding a capabilities check and a nonce check before the functionality is run:
1076 1077 1078 1079 1080 1081 1082 1083 | function Maspik_allow_sharing_callback() { // Check nonce check_ajax_referer('maspik_allow_sharing_nonce', 'security'); // Check user capabilities if (!current_user_can('manage_options')) { wp_die(__('Permission error', 'contact-forms-anti-spam')); } |
Missing sanitize_callback When Registering Settings
The plugin registers numerous settings using register_setting(). None of the registrations had a sanitize_callback to restrict what the settings can be. Adding that would make things more secure.
The update tried to implement that for some settings, with the code to have the values passed through sanitize_text_field(), but it wasn’t implemented properly. We have notified the developer of that and are putting together a post on how to properly implement that, as there doesn’t seem to be good documentation of that.
Other settings didn’t get that added at all.
IP Address Validation
The plugin was using the sanitization function sanitize_text_field() when getting the IP address for a request to the website. It would be better to validate if the value is an IP address using code. The new version added that:
if (filter_var($ip_address, FILTER_VALIDATE_IP)) { |
Misuse of esc_url_raw()
In the file from a third-party library, the escaping function esc_url_raw() is used when esc_url() should be used in several places. As, esc_url_raw() is for use when sanitizing a “URL for database or redirect usage,” which isn’t what is occurring when it is used. We notified the developer of the library about that as well. That was resolved by changing to the correct escaping function.
Tracking Issue Caused by Image Offloading
On an admin page of the plugin, the plugin was offloading an image to the developer’s website, which isn’t permitted by the WordPress Plugin Guidelines because of the possibility of it being used for tracking. That was resolved by including the image in the plugin.
Lack of Protection Against Direct Access to PHP Files
The plugin’s .php files that didn’t appear to be intended to be directly accessed don’t contain protection against direct access, other than the plugin’s main file. We didn’t see anything that could be exploited in the files without the restriction in place, but restricting access to them would ensure that there isn’t any issue with that. That protection has now been added to many, but not all the files. We noted that with the developer.