WordPress Plugin Developers Are Still Creating Vulnerabilities by Improperly Using the permission_callback for WordPress Rest API Endpoints
Back in November, the Automattic owned WPScan claimed there had been a vulnerability in a plugin that extends the very popular ecommerce plugin WooCommerce, which is also owned by Automattic. WPScan only got around to releasing any information about the claimed vulnerability this month. When we went to check on that, we found that the relevant code is still vulnerable, though less vulnerable than it was before. If the developer of the plugin was properly implementing the built-in security when using WordPress’ REST API they wouldn’t still have the vulnerability.
We are now four years in with the REST API being available in WordPress, but plugin developers are still not implementing a basic security element it introduced correctly. So it seems worth going through what is going wrong and how it can be fairly easily be fixed.
The vulnerability involved allowing even those not logged in to WordPress to change the settings of the plugin, Product Catalog Enquiry (Product Catalog Mode For WooCommerce). The code that caused that is in the file /classes/class-woocommerce-catalog-enquiry.php. That code registers a function mvx_catalog_save_enquiry(), which handles saving the settings, through the WordPress REST API. That looked like this in the version before WPScan said it was fixed:
126 127 128 129 130 | register_rest_route( 'mvx_catalog/v1', '/save_enquiry', [ 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'mvx_catalog_save_enquiry' ), 'permission_callback' => array( $this, 'catalog_permission' ) ] ); |
As the function is for changing settings, the permission_callback should check if the user has the manage_options capability. But the permission_callback simply returns true:
150 151 152 | public function catalog_permission() { return true; } |
The new version didn’t change that. Instead, it added a capability check before calling the REST API registration:
86 87 | if (current_user_can('manage_options')) { add_action( 'rest_api_init', array( $this, 'catalog_rest_routes_react_module' ) ); |
The problem with that change is that while it restricts access to Administrators, it doesn’t prevent cross-site request forgery (CSRF). If they had instead correctly set the permission_callback, then WordPress automatically adds a nonce check to prevent CSRF when running the code. So there is still a CSRF/settings change vulnerability. Meaning an attacker could cause a logged in Administrator to change the settings without them intending it.
Somehow WPScan missed that problem. That stands out more when they didn’t provide the information needed to catch that in a timely manner and when the vulnerable plugin extends a plugin from their owner Automattic.
The proper way to fix this would be to add the capabilities check to permission_callback function:
123 124 125 | public function catalog_permission() { return current_user_can('manage_options'); } |
The developer also needs to add a valid nonce to requests sent to the REST API.
We have reached out to the developer to let them know they still haven’t fully resolved this.
Need Help Fixing a Vulnerability in Your Plugin?
We are happy to help you get it fixed for free, since warning the customers of our service about vulnerabilities in their plugins isn't very useful if there isn't a fixed version available.Plugin Security Scorecard Grade for Product Catalog Enquiry
Checked on July 31, 2024See issues causing the plugin to get less than A+ grade