Full Fix For WordPress Plugin Vulnerability Delayed Over a Year Due Corner Cutting by Claimed Security Researchers
On Tuesday we had what appeared to be a hacker sending multiple requests to our website attempting to access code that we found was in a WordPress plugin with 100,000+ installs, Relevanssi. (We don’t use the plugin.) Looking at the code, we found that the related code was not secure in the latest version of the plugin. Several steps later, we found that it was supposed to have been secured over a year ago, but wasn’t. That involved a claimed security researcher and another WordPress security provider, both of which don’t provide the needed information to vet their claims and make sure things actually get fixed (or make sure they are actually vulnerabilities). This is a reoccurring problem and to help warn about that, we are now compiling a database of claimed WordPress security researchers with warnings if they are causing problems like that (or a notice that they are a reliable source, for the few that are). After doing work we shouldn’t have had to do, we were able to work with the developer of the plugin to get the problem properly addressed.
Missing Capability Check
Getting back to the code being targeted, in the plugin’s file /lib/init.php, the plugin has the function relevanssi_export_log_check() run after active plugins have been loaded while WordPress is generating a page:
79 | add_action( 'plugins_loaded', 'relevanssi_export_log_check' ); |
That makes the function accessible to even those not logged in to WordPress. The function permits exporting the plugin’s logging, so it shouldn’t be generally accessible. There should be a capability check in the code to limit access, but there wasn’t:
47 48 49 50 51 52 53 54 55 56 | function relevanssi_export_log_check() { if ( isset( $_REQUEST['relevanssi_export'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification, just checking the parameter exists. check_admin_referer( 'relevanssi_export_logs', '_relevanssi_export_nonce' ); relevanssi_export_log(); } if ( isset( $_REQUEST['relevanssi_export_clicks'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification, just checking the parameter exists. check_admin_referer( 'relevanssi_export_logs', '_relevanssi_export_nonce' ); function_exists( 'relevanssi_export_click_log' ) && relevanssi_export_click_log(); } } |
There is a nonce check, which is used to prevent cross-site request forgery (CSRF). That isn’t really needed when simply exporting data in a file to served to the requestor, like the code does here. While that type of check normally does the equivalent of a capability, it doesn’t always, as can be seen by an exploited vulnerability in Elementor. The WordPress documentation is very clear that it shouldn’t be used that way:
Nonces should never be relied on for authentication, authorization, or access control. Protect your functions using
current_user_can()
, and always assume nonces can be compromised.
We reached out to the developer about that and within hours they released an update to correct that:
497 498 499 500 501 502 503 504 505 506 | function relevanssi_export_log_check() { if ( isset( $_REQUEST['relevanssi_export'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification, just checking the parameter exists. check_admin_referer( 'relevanssi_export_logs', '_relevanssi_export_nonce' ); relevanssi_export_log(); } if ( isset( $_REQUEST['relevanssi_export_clicks'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification, just checking the parameter exists. check_admin_referer( 'relevanssi_export_logs', '_relevanssi_export_nonce' ); function_exists( 'relevanssi_export_click_log' ) && relevanssi_export_click_log(); } } |
Krzysztof Zając of CERT PL And Wordfence Didn’t Provide This Detail
The information above is what an actual researcher would provide when bringing up a vulnerability, but when that didn’t have before with this code. In February or March of last year, Krzysztof Zając of CERT PL And Wordfence made this vague claim about the code:
The Relevanssi – A Better Search plugin for WordPress is vulnerable to unauthorized access of data due to a missing capability check on the relevanssi_export_log_check() function in all versions up to, and including, 4.22.0. This makes it possible for unauthenticated attackers to export the query log data. The vendor has indicated that they may look into adding a capability check for proper authorization control, however, this vulnerability is theoretically patched as is.
As written, it doesn’t really make sense, as they claim there was a missing capability check, but the issue apparently was resolved even though the capability check is missing. If you did further checking, which you shouldn’t have to, it would appear they are treating this as fixed because a nonce check was added. Even though that doesn’t fix the issue.
If either of those parties had provided the details shown above or provide a proof of concept, we could have seen the problem and worked with the developer to get fixed last year, instead of that happening a year later.
This highlights the importance of providing that information and the problem of claimed researcher cutting corners to the detriment of the WordPress community.